如何解决Flutter:如何使TextField专注于提交?
我正在使用https://pub.dev/packages/flutter_tags作为标签输入。通过按下键盘上的Submit(提交)并清除TextInput字段,可以将标签添加到标签数组中。
现在我有一个问题,提交时键盘也关闭了。因此,您必须为每个标签再次按下该字段,这不是问题。有关如何关闭键盘的说明很多,但是没有关于如何保持键盘打开的说明。
当按下Submit(提交)时,该字段失去焦点,因此键盘关闭。不幸的是,我的想法是没有将成功的新焦点放在onSubmitted上。不幸的是,这里什么也没发生:
TextField(
controller: myController,focusNode: myFocusNode,// more code
onSubmitted: (String str) {
myController.clear();
myFocusNode.requestFocus();
}
)
亲切的问候,
Jakob
解决方法
您可以在下面复制粘贴运行完整代码
以下代码使用官方示例代码并修改Demo2
代码段
TextField(
controller: myController,decoration: InputDecoration(
icon: Icon(Icons.person),labelText: "add tag with focus",),focusNode: myFocusNode,onSubmitted: (val) {
setState(() {
_items.add(val);
});
myController.clear();
myFocusNode.requestFocus();
},
工作演示
完整代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_tags/flutter_tags.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tags Demo',theme: ThemeData(
primarySwatch: Colors.blueGrey,home: MyHomePage(title: 'Flutter Tags'),);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key,this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
FocusNode myFocusNode = FocusNode();
TextEditingController myController = TextEditingController();
TabController _tabController;
ScrollController _scrollViewController;
final List<String> _list = [
'0','SDK','plugin updates','Facebook','哔了狗了QP又不够了','Kirchhoff','Italy','France','Spain','美','Dart','Foo','Select','lorem ip','9','Star','Flutter Selectable Tags','1','Hubble','2','Input flutter tags','A B C','8','Android Studio developer','welcome to the jungle','Gauss','美术','互联网','炫舞时代','篝火营地',];
bool _symmetry = false;
bool _removeButton = true;
bool _singleItem = false;
bool _startDirection = false;
bool _horizontalScroll = false;
bool _withSuggesttions = false;
int _count = 0;
int _column = 0;
double _fontSize = 14;
String _itemCombine = 'withTextBefore';
String _onPressed = '';
List _icon = [Icons.home,Icons.language,Icons.headset];
@override
void initState() {
super.initState();
_tabController = TabController(length: 2,vsync: this);
_scrollViewController = ScrollController();
_items = _list.toList();
}
List _items;
final GlobalKey<TagsState> _tagStateKey = GlobalKey<TagsState>();
@override
Widget build(BuildContext context) {
//List<Item> lst = _tagStateKey.currentState?.getAllItem; lst.forEach((f) => print(f.title));
return Scaffold(
body: NestedScrollView(
controller: _scrollViewController,headerSliverBuilder: (BuildContext context,bool boxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text("flutter tags"),centerTitle: true,pinned: true,expandedHeight: 0,floating: true,forceElevated: boxIsScrolled,bottom: TabBar(
isScrollable: false,indicatorSize: TabBarIndicatorSize.label,labelStyle: TextStyle(fontSize: 18.0),tabs: [
Tab(text: "Demo 1"),Tab(text: "Demo 2"),],controller: _tabController,)
];
},body: TabBarView(
controller: _tabController,children: [
CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey[300],width: 0.5))),margin:
EdgeInsets.symmetric(horizontal: 10,vertical: 10),child: ExpansionTile(
title: Text("Settings"),children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _removeButton,onChanged: (a) {
setState(() {
_removeButton = !_removeButton;
});
}),Text('Remove Button')
],onTap: () {
setState(() {
_removeButton = !_removeButton;
});
},Padding(
padding: EdgeInsets.all(5),GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _symmetry,onChanged: (a) {
setState(() {
_symmetry = !_symmetry;
});
}),Text('Symmetry')
],onTap: () {
setState(() {
_symmetry = !_symmetry;
});
},DropdownButton(
hint: _column == 0
? Text("Not set")
: Text(_column.toString()),items: _buildItems(),onChanged: (a) {
setState(() {
_column = a;
});
},Row(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _horizontalScroll,onChanged: (a) {
setState(() {
_horizontalScroll =
!_horizontalScroll;
});
}),Text('Horizontal scroll')
],onTap: () {
setState(() {
_horizontalScroll = !_horizontalScroll;
});
},GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _singleItem,onChanged: (a) {
setState(() {
_singleItem = !_singleItem;
});
}),Text('Single Item')
],onTap: () {
setState(() {
_singleItem = !_singleItem;
});
},Column(
children: <Widget>[
Text('Font Size'),Row(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Slider(
value: _fontSize,min: 6,max: 30,onChanged: (a) {
setState(() {
_fontSize = (a.round()).toDouble();
});
},Text(_fontSize.toString()),Padding(
padding:
EdgeInsets.symmetric(horizontal: 20),Container(
height: 30,width: 30,//color: Colors.blueGrey,child: IconButton(
padding: EdgeInsets.all(0),//color: Colors.white,icon: Icon(Icons.add),onPressed: () {
setState(() {
_count++;
_items.add(_count.toString());
//_items.removeAt(3); _items.removeAt(10);
});
},Padding(
padding:
EdgeInsets.symmetric(horizontal: 5),//color: Colors.grey,icon: Icon(Icons.refresh),onPressed: () {
setState(() {
_items = _list.toList();
});
},Padding(
padding: EdgeInsets.all(20),_tags1,Container(
padding: EdgeInsets.all(20),child: Column(
children: <Widget>[
Divider(
color: Colors.blueGrey,Padding(
padding: EdgeInsets.symmetric(vertical: 20),child: Text(_onPressed),)),])),CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey[300],children: <Widget>[
GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _withSuggesttions,onChanged: (a) {
setState(() {
_withSuggesttions =
!_withSuggesttions;
});
}),Text('Suggestions')
],onTap: () {
setState(() {
_withSuggesttions = !_withSuggesttions;
});
},Padding(
padding: EdgeInsets.all(20),DropdownButton(
hint: Text(_itemCombine),items: _buildItems2(),onChanged: (val) {
setState(() {
_itemCombine = val;
});
},GestureDetector(
child: Row(
children: <Widget>[
Checkbox(
value: _startDirection,onChanged: (a) {
setState(() {
_startDirection = !_startDirection;
});
}),Text('Start Direction')
],onTap: () {
setState(() {
_startDirection = !_startDirection;
});
},_tags2,TextField(
controller: myController,decoration: InputDecoration(
icon: Icon(Icons.person),onSubmitted: (val) {
setState(() {
_items.add(val);
});
myController.clear();
myFocusNode.requestFocus();
},);
}
Widget get _tags1 {
return Tags(
key: _tagStateKey,symmetry: _symmetry,columns: _column,horizontalScroll: _horizontalScroll,//verticalDirection: VerticalDirection.up,textDirection: TextDirection.rtl,heightHorizontalScroll: 60 * (_fontSize / 14),itemCount: _items.length,itemBuilder: (index) {
final item = _items[index];
return ItemTags(
key: Key(index.toString()),index: index,title: item,pressEnabled: true,activeColor: Colors.blueGrey[600],singleItem: _singleItem,splashColor: Colors.green,combine: ItemTagsCombine.withTextBefore,image: index > 0 && index < 5
? ItemTagsImage(
//image: AssetImage("img/p$index.jpg"),child: Image.network(
"http://www.clipartpanda.com/clipart_images/user-66327738/download",width: 16 * _fontSize / 14,height: 16 * _fontSize / 14,))
: (1 == 1
? ItemTagsImage(
image: NetworkImage(
"https://d32ogoqmya1dw8.cloudfront.net/images/serc/empty_user_icon_256.v2.png"),)
: null),icon: (item == '0' || item == '1' || item == '2')
? ItemTagsIcon(
icon: _icon[int.parse(item)],)
: null,removeButton: _removeButton
? ItemTagsRemoveButton(
onRemoved: () {
setState(() {
_items.removeAt(index);
});
return true;
},textScaleFactor:
utf8.encode(item.substring(0,1)).length > 2 ? 0.8 : 1,textStyle: TextStyle(
fontSize: _fontSize,onPressed: (item) => print(item),);
},);
}
// Position for popup menu
Offset _tapPosition;
Widget get _tags2 {
//popup Menu
final RenderBox overlay = Overlay.of(context).context?.findRenderObject();
ItemTagsCombine combine = ItemTagsCombine.onlyText;
switch (_itemCombine) {
case 'onlyText':
combine = ItemTagsCombine.onlyText;
break;
case 'onlyIcon':
combine = ItemTagsCombine.onlyIcon;
break;
case 'onlyIcon':
combine = ItemTagsCombine.onlyIcon;
break;
case 'onlyImage':
combine = ItemTagsCombine.onlyImage;
break;
case 'imageOrIconOrText':
combine = ItemTagsCombine.imageOrIconOrText;
break;
case 'withTextAfter':
combine = ItemTagsCombine.withTextAfter;
break;
case 'withTextBefore':
combine = ItemTagsCombine.withTextBefore;
break;
}
return Tags(
key: Key("2"),verticalDirection:
_startDirection ? VerticalDirection.up : VerticalDirection.down,textDirection: _startDirection ? TextDirection.rtl : TextDirection.ltr,textField: TagsTextField(
autofocus: false,textStyle: TextStyle(
fontSize: _fontSize,//height: 1
),enabled: true,constraintSuggestion: true,suggestions: _withSuggesttions
? [
"One","two","android","Dart","flutter","test","tests","androids","androidsaaa","Test","suggest","suggestions","互联网","last","lest","炫舞时代"
]
: null,onSubmitted: (String str) {
print("onSubmitted $str");
setState(() {
_items.add(str);
});
},itemBuilder: (index) {
final item = _items[index];
return GestureDetector(
child: ItemTags(
key: Key(index.toString()),pressEnabled: false,activeColor: Colors.green[400],combine: combine,image: index > 0 && index < 5
? ItemTagsImage(image: AssetImage("img/p$index.jpg"))
: (1 == 1
? ItemTagsImage(
image: NetworkImage(
"https://image.flaticon.com/icons/png/512/44/44948.png"))
: null),icon: (item == '0' || item == '1' || item == '2')
? ItemTagsIcon(
icon: _icon[int.parse(item)],)
: null,removeButton: ItemTagsRemoveButton(
backgroundColor: Colors.green[900],onRemoved: () {
setState(() {
_items.removeAt(index);
});
return true;
},textScaleFactor:
utf8.encode(item.substring(0,textStyle: TextStyle(
fontSize: _fontSize,onTapDown: (details) => _tapPosition = details.globalPosition,onLongPress: () {
showMenu(
//semanticLabel: item,items: <PopupMenuEntry>[
PopupMenuItem(
child: Text(item,style: TextStyle(color: Colors.blueGrey)),enabled: false,PopupMenuDivider(),PopupMenuItem(
value: 1,child: Row(
children: <Widget>[
Icon(Icons.content_copy),Text("Copy text"),context: context,position: RelativeRect.fromRect(
_tapPosition & Size(40,40),Offset.zero &
overlay
.size) // & RelativeRect.fromLTRB(65.0,40.0,0.0,0.0),)
.then((value) {
if (value == 1) Clipboard.setData(ClipboardData(text: item));
});
},);
}
List<DropdownMenuItem> _buildItems() {
List<DropdownMenuItem> list = [];
int count = 19;
list.add(
DropdownMenuItem(
child: Text("Not set"),value: 0,);
for (int i = 1; i < count; i++)
list.add(
DropdownMenuItem(
child: Text(i.toString()),value: i,);
return list;
}
List<DropdownMenuItem> _buildItems2() {
List<DropdownMenuItem> list = [];
list.add(DropdownMenuItem(
child: Text("onlyText"),value: 'onlyText',));
list.add(DropdownMenuItem(
child: Text("onlyIcon"),value: 'onlyIcon',));
list.add(DropdownMenuItem(
child: Text("onlyImage"),value: 'onlyImage',));
list.add(DropdownMenuItem(
child: Text("imageOrIconOrText"),value: 'imageOrIconOrText',));
list.add(DropdownMenuItem(
child: Text("withTextBefore"),value: 'withTextBefore',));
list.add(DropdownMenuItem(
child: Text("withTextAfter"),value: 'withTextAfter',));
return list;
}
}
,
只要用户需要填写表格,您就需要将myFocusNode
传递给requestFocus()
。假设您有一个称为completed
的布尔条件,则可以执行以下操作:
if (completed) {
focus.unfocus();
} else {
focus.requestFocus(myFocusNode);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。