[英]How to shift focus to the next TextField in Flutter?
截屏:
只需使用:
textInputAction: TextInputAction.next
: 將光標移動到下一個字段。
textInputAction: TextInputAction.done
: 關閉鍵盤。
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'TextField A'),
textInputAction: TextInputAction.next, // Moves focus to next.
),
TextField(
decoration: InputDecoration(hintText: 'TextField B'),
textInputAction: TextInputAction.next, // Moves focus to next.
),
TextField(
decoration: InputDecoration(hintText: 'TextField C'),
textInputAction: TextInputAction.done, // Hides the keyboard.
),
],
),
);
}
找到了實現它的方法。
顯示下一個圖標而不是完成 - 將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() 方法中初始化 FocusNode 並在父 Widget 的 dispose() 中進行處置。 - @AntonDerevyanko
更新:在沒有FocusNode
和FocusScopeNode
情況下也可以實現相同的效果,只需調用FocusScope.of(context).nextFocus()
,看看如何做到這一點的CopsOnRoad 解決方案。 有關更多信息,請查看文檔。
這是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
),
不知道確切原因,但 onFieldSubmitted 有時會跳過一個或多個字段,在這種情況下 onEditingComplete 按預期工作
TextFormField(
decoration: InputDecoration(hintText: "Username"),
textInputAction: TextInputAction.next,
onEditingComplete : (_) => FocusScope.of(context).nextFocus(), // focus to next
),
TextFormField(
decoration: InputDecoration(hintText: "Password"),
textInputAction: TextInputAction.done,
onEditingComplete : (_) => 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(),
),
)
],
)
我嘗試只添加textInputAction
屬性,它在沒有其他任何東西的情況下工作。
也許新版本的 Flutter 改進了這個功能? 或者需要 StatefulWidget 和 FormKey 才能正常工作?
我在 Flutter 上(通道穩定,1.22.5)
試一試:
class MyForm extends StatefulWidget {
@override
State createState() => _myFormState();
}
class _myFormState extends State<MyForm> {
//
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
// *** Just added this
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: 'Input 1',
),
),
TextFormField(
textInputAction: TextInputAction.done,
decoration: const InputDecoration(
labelText: 'Input 2',
),
)
],
),
);
}
}
我使用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),
),
感謝@haytham-anmar 分享的擴展和@natesh-bhat 的擴展!
但這對於 Flutter 的未來版本將不再適用,因為EditableText
樹發生了重大變化(參考:將文本編輯操作移動到 EditableTextState #90684 )。
請考慮以下遷移代碼:
遷移前:
extension Utility on BuildContext {
void nextEditableTextFocus() {
do {
FocusScope.of(this).nextFocus();
} while (FocusScope.of(this).focusedChild?.context?.widget is! EditableText);
}
}
遷移后:
extension Utility on BuildContext {
void nextEditableTextFocus() {
do {
FocusScope.of(this).nextFocus();
} while (FocusScope.of(this).focusedChild!.context == null);
}
}
您可以使用此輔助函數聚焦下一個文本字段:
void focusNextTextField(BuildContext context) {
do {
var foundFocusNode = FocusScope.of(context).nextFocus();
if (!foundFocusNode) return;
} while (FocusScope.of(context).focusedChild.context.widget is! EditableText);
}
我希望它有用
textInputAction: TextInputAction.next,
onEditingComplete: () {
FocusScope.of(context).nextFocus();
},
onSubmitted: (value) {
if (value.isNotEmpty) {
FocusScope.of(context).nextFocus();
}
},
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.