我是Flutter的新手。
我正在使用以下窗口小部件构建具有多个文本输入的表单:Form,TextFormField。出现的键盘不显示“下一个”(应将焦点转移到下一个字段)字段操作,而是“完成”操作(隐藏键盘)。
我在官方文档中寻找任何提示,没有发现直接可以做的事情。我虽然登陆了FocusNode(cookbook,api doc)。它提供了通过应用程序上的某些按钮或任何其他操作来转移焦点的机制,但我希望它位于键盘中。
Answers:
屏幕截图:
您可以不使用FocusNode
或进行操作FocusScopeNode
。
@override
Widget build(BuildContext context) {
final node = FocusScope.of(context);
return Scaffold(
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'TextField A'),
textInputAction: TextInputAction.next,
onEditingComplete: () => node.nextFocus(), // Move focus to next
),
TextField(
decoration: InputDecoration(hintText: 'TextField B'),
textInputAction: TextInputAction.next,
onEditingComplete: () => node.nextFocus(), // Move focus to next
),
TextField(
decoration: InputDecoration(hintText: 'TextField C'),
textInputAction: TextInputAction.done,
onSubmitted: (_) => node.unfocus(), // Submit and hide keyboard
),
],
),
);
}
onChanged
property来实现。
找到了一种方法来实现它。
显示下一个图标而不是完成-将textInputAction
参数设置为TextInputAction.next
使用onFieldSubmitted
回调请求下一个字段的焦点节点。
class FormWidget extends StatelessWidget{
final focus = FocusNode();
@override
Widget build(BuildContext context) {
return Form(
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
autofocus: true,
decoration: InputDecoration(labelText: "Input 1"),
onFieldSubmitted: (v){
FocusScope.of(context).requestFocus(focus);
},
),
TextFormField(
focusNode: focus,
decoration: InputDecoration(labelText: "Input 2"),
),
],
),
),
);
}
}
编辑:如文档所述(flutter.io/docs/cookbook/forms/focus),-我们还需要管理FocusNode生命周期。因此,请使用init()方法中的init FocusNode并将其放置在父Widget的dispose()中。-@AntonDerevyanko
更新:如果没有FocusNode
和FocusScopeNode
,只需调用FocusScope.of(context).nextFocus()
,看看CopsOnRoad解决方案的实现方法,就可以实现相同的目的。有关更多信息,请检查doc。
onFieldSubmitted
的第二场比赛requestFocus
的第三场
FocusScope.of(context).requestFocus(focus);
您可以简单地致电focus.requestFocus()
这是CopsOnRoad答案的其他步骤,因为当文本字段之间存在可聚焦的小部件时,它在更复杂的UI中不起作用,例如:
解决方案是继续调用“ nextFocus()”直到找到“ EditableText”
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: "TextField A"),
textInputAction: textInputAction1,
onSubmitted: (_) => context.nextEditableTextFocus(), // move focus to next
),
TextField(
decoration: InputDecoration(hintText: "TextField B"),
textInputAction: textInputAction2,
onSubmitted: (_) => context.nextEditableTextFocus(), // move focus to next
),
MaterialButton(
onPressed: () {},
color: Colors.amber,
),
TextField(
decoration: InputDecoration(hintText: "TextField C"),
textInputAction: textInputAction3,
onSubmitted: (_) => FocusScope.of(context).unfocus(), // submit and hide keyboard
),
],
),
);
}
扩展方法是:
extension Utility on BuildContext {
void nextEditableTextFocus() {
do {
FocusScope.of(this).nextFocus();
} while (FocusScope.of(this).focusedChild.context.widget is! EditableText);
}
}
对于TextFormFeild使用,可以使用onFieldSubmitted
TextFormField(
decoration: InputDecoration(hintText: "Username"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(), // focus to next
),
TextFormField(
decoration: InputDecoration(hintText: "Password"),
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => FocusScope.of(context).unfocus(), // Unfocus and hide keyboard
),
对我而言,此方法有效,在输入第一个数字时移至下一个输入
Row(
children: <Widget>[
Expanded(
child: TextFormField(
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).nextFocus(),
controller:c1 ,)
),
SizedBox(
width: 20.0,
),
Expanded(
child: TextFormField(
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).nextFocus(),
controller:c2 ,),
),
SizedBox(
width: 20.0,
),
Expanded(
child: TextFormField(
controller:c3 ,
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).nextFocus(),),
),
SizedBox(
width: 20.0,
),
Expanded(
child: TextFormField(
controller:c4 ,
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).nextFocus(),),
),
SizedBox(
width: 20.0,
),
Expanded(
child: TextFormField(
controller:c5 ,
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).nextFocus(),),
),
SizedBox(
width: 20.0,
),
Expanded(
child: TextFormField(
controller:c6 ,
textInputAction: TextInputAction.next,
onChanged: (_) => FocusScope.of(context).unfocus(),
),
)
],
)
我用
onSubmitted
代替onFieldSubmitted
范例程式码
TextField(
textInputAction: TextInputAction.next,
onSubmitted: (_) => FocusScope.of(context).nextFocus(),
controller: _phoneController,
decoration: const InputDecoration(
labelText: 'Phone number',
),
style: TextStyle(fontSize: 16.0, color: Colors.white),
),