首页 > 解决方案 > tab keypress/TextInputAction.next 导航到下一个输入表单

问题描述

我有一个非常标准的登录表单。在 Web 上,标签导航是非常标准的——按电子邮件文本字段上的 tab 键导航到密码文本字段(反之亦然)。在移动设备上,TextInputAction.next 应该以相同的方式工作。但是我如何在颤动中做到这一点?

这是我的简单登录表单:

class LoginFormState extends State<LoginForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Scaffold(
        body: Form(
      key: _formKey,
      child: Padding(
          padding: EdgeInsets.all(10.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Enter your email'),
                keyboardType: TextInputType.emailAddress,
                textInputAction: TextInputAction.next,
                autovalidate: true,
                style: TextStyle(
                  fontSize: 28,
                ),
              ),
              TextFormField(
                obscureText: true,
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Enter your API key'),
                style: TextStyle(
                  fontSize: 28,
                ),
              ),

            ],
          )),
    ));

标签: flutterdart

解决方案


你需要为每个创建一个FocusNodeTextFormField,然后你需要将它分配给每个TextFormField,然后在onEditingComplete你需要调用requestFocus的参数FocusNode中的下一个TextFormField

查看此官方教程以获取更多信息。

并检查具有简化 API 的flutter_form_bloc来执行此操作。

class LoginForm extends StatefulWidget {
  LoginForm({Key key}) : super(key: key);

  _LoginFormState createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> {
  final _formKey = GlobalKey<FormState>();
  FocusNode _apiKeyFocusNode;
  FocusNode _otherFieldFocusNode;

  @override
  void initState() {
    super.initState();
    _apiKeyFocusNode = FocusNode();
    _otherFieldFocusNode = FocusNode();
  }

  @override
  void dispose() {
    // Clean up the focus node when the Form is disposed.
    _apiKeyFocusNode.dispose();
    _otherFieldFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Form(
      key: _formKey,
      child: Padding(
          padding: EdgeInsets.all(10.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(
                    labelText: 'Enter your email'),
                keyboardType: TextInputType.emailAddress,
                textInputAction: TextInputAction.next,
                autovalidate: true,
                style: TextStyle(
                  fontSize: 28,
                ),
                onEditingComplete: () => _apiKeyFocusNode.requestFocus(),
              ),
              TextFormField(
                focusNode: _apiKeyFocusNode,
                obscureText: true,
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Enter your API key'),
                style: TextStyle(
                  fontSize: 28,
                ),
                onEditingComplete: () => _otherFieldFocusNode.requestFocus(),
              ),
              TextFormField(
                focusNode: _otherFieldFocusNode,
                obscureText: true,
                autocorrect: false,
                decoration: InputDecoration(labelText: 'Other field'),
                style: TextStyle(
                  fontSize: 28,
                ),
              ),
            ],
          )),
    ));
  }
}


推荐阅读