代码之家  ›  专栏  ›  技术社区  ›  Harsh Bhikadia

如何在flatter中将焦点转移到下一个textfield?

  •  4
  • Harsh Bhikadia  · 技术社区  · 7 年前

    我是新来的。

    我在官方文件中寻找任何提示,没有发现任何可以直接做的事情。 cookbook , api doc ). 它提供了一种机制,可以通过一些按钮或应用程序上的任何其他操作转移焦点,但我希望它是在 .

    1 回复  |  直到 5 年前
        1
  •  132
  •   CopsOnRoad    5 年前

    截图:

    enter image description here


    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
            ),
          ],
        ),
      );
    }
    
        2
  •  90
  •   CopsOnRoad    6 年前

    找到了实现它的方法。

    1. 显示下一个图标而不是完成-设置 textInputAction 参数到 TextInputAction.next

    2. 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"),
                  ),
                ],
              ),
            ),
          );
        }
      }
      

    编辑:如文件所述(flatter.io/docs/cookbook/forms/focus文件),-我们还需要管理FocusNode生命周期。因此,在父窗口小部件的init()方法中使用init FocusNode,在dispose()中使用dispose。-@安东德雷维扬科

    FocusNode FocusScopeNode ,只需拨打 FocusScope.of(context).nextFocus() ,看看 CopsOnRoad solution 如何做到这一点。更多信息请查看 doc .

        3
  •  12
  •   Haytham Anmar    5 年前

    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);
      }
    }
    
        4
  •  6
  •   Swaroop Maddu    6 年前

    对于TextFormFeild use,可以使用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
            ),
    
        5
  •  6
  •   Zeeshan Mehdi    5 年前

    对我来说,输入第一个数字时,它会移到下一个输入

    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(),
                              ),
                        )
                      ],
                    )
    
        6
  •  3
  •   funder7    5 年前

    我试着把 textInputAction 财产,它没有任何其他的工作。

    或者需要StatefulWidget&FormKey才能工作?

    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',
                ),
              )
            ],
          ),
        );
      }
    }
    
        7
  •  1
  •   Quick learner    5 年前

    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),
                  ),
    
        8
  •  0
  •   Natesh bhat    5 年前

    您可以使用此帮助函数来聚焦下一个文本字段:

    void focusNextTextField(BuildContext context) {
      do {
        var foundFocusNode = FocusScope.of(context).nextFocus();
        if (!foundFocusNode) return;
      } while (FocusScope.of(context).focusedChild.context.widget is! EditableText);
    }