沃梦达 / IT编程 / 移动开发 / 正文

Flutter基本组件Basics Widget学习

本文详细讲解了Flutter基本组件Basics Widget,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

然后在 TextFiled 中传入这个 controller

TextField(
  controller: _tfController,
  ...
)

最后就可以通过 : print(_tfController.text) 来获得输入框的内容

2.5.1.3 通过 controller 监听文本内容变化

可以通过 onChange 来监听文本, controller 可以通过设置监听器来监听文本,如下:


  @override
  void initState() {
    super.initState();
    _tfController.addListener(() { 
      print(_tfController.text);
    });
  }

controller 的功能更多,除了监听文本,还可以设置默认值、选择文本等,这里就不多赘述。

2.5.1.4 控制焦点

可以使用 FocusNodeFocusScopeNode 来控制焦点。默认情况下是由 FocusScope 来管理,可以在这个范围内通过 FocusScopeNode 在输入框之间移动焦点、设置默认焦点。

我们可以通过下面代码来获取当前 Widget 树中默认的 FocusScopeNode:


focusScopeNode = FocusScope.of(context)

拿到句柄后,可以使用下面代码来获取焦点:


focusScopeNode.requestFocus(focusNode);

其中 focucsNode 是为 TextField 创建的 FocusNode, 这个操作可以让该 TextField 获取焦点。 调用 focusNode.unfocus() 可以取消焦点。

2.5.1.5 监听焦点状态改变事件

通过 FocusNode 可以监听焦点改变的事件:


focusNode.addListener((){
   print(focusNode.hasFocus);
})

true为获取焦点,false为失去焦点

2.5.2 表单

表单Form 对输入框进行分组和统一操作。 就像 Android 的原生组件 RadioGroup 之于 RadioButton 一样, Form 可以管理内容校验、输入框重置等。

Form 继承自 StatefulWidget,其状态管理在 FormState 里面,来看看 From 的定义:


class Form extends StatefulWidget {
  const Form({
    Key? key,
    required this.child,
    @Deprecated(
      'Use autovalidateMode parameter which provides more specific '
      'behavior related to auto validation. '
      'This feature was deprecated after v1.19.0.',
    )
    this.autovalidate = false,
    this.onWillPop,
    this.onChanged,
    AutovalidateMode? autovalidateMode,
  })
  ...
  • autovalidate
    是否自动校验输入内容,当为true时,每一个 FormField 内容发生变化时都会校验合法性,并直接显示错误信息,否则就需要通过调用 FormState.validate() 来手动校验
    v1.19 已经废弃了,改成使用 AutovalidateMode
  • autovalidateMode
    自动校验模式,是上面的替换,它有三个枚举值:
    disable:当 FormField 内容改变时不做校验
    always:即使用户没有用户交互也要校验合法性
    onUserInteraction:只有在用户交互时才会去校验合法性
  • onWillPop
    决定 Form 所在的路由是否可以直接返回。该回调返回一个 Future 对象,如果 Future 的最终结果是 false,则当前路由不会返回,如果为 true,则会返回到上一个路由。
    这个属性通常是用于拦截返回按钮的
  • onChanged
    Form 的任意一个 FormField 内容发生改变时就会调用该方法
2.5.2.1 FormField

Form 的子孙元素是 FormField 类型,FormField 是一个抽象类,定义了几个属性, FormState 内部通过他们来完成操作, FormField 部分定义如下:


  const FormField({
    Key? key,
    required this.builder,
    this.onSaved,
    this.validator,
    this.initialValue,
    @Deprecated(
      'Use autovalidateMode parameter which provides more specific '
      'behavior related to auto validation. '
      'This feature was deprecated after v1.19.0.',
    )
    this.autovalidate = false,
    this.enabled = true,
    AutovalidateMode? autovalidateMode,
    this.restorationId,
  })
  • onSaved
    保存时的回调
  • validator
    验证合法性的回调
  • initValue
    初始值

为了方便使用, Flutter 提供了一个 TextFormFild 组件,继承自 FormField 类,还包装了 TextFileld ,可以直接当成 Form 的 FormField 来使用, 相当于用 Form 来管理 TextField

2.5.2.2 FormState

Form 表单的状态类就是 FormState, 可以通过 Form.of 或者 GlobalKey 获得,通过获得它来对 Form 的子孙 FormField 进行统一操作。

FormState 常用的三个方法:

  • FormState.validate():调用此方法后, 会调用 Form 子孙 FormField.validate() 回调,如果有一个检验失败,那么会返回 false,这样所有校验失败的 Widget 都会给出错误提示
  • FormState.save():调用此方法后,会调用 子孙的 FormFild.save() 回调,用于保存表单内容
  • FormState.reset(): 会将子孙 FormField 的内容清空
2.5.2.3 示例

我们做一个用户登录的程序,再点击登录前需要做到输入检查:

  • 用户名不能为空,如果为空则提示“用户名不能为空”
  • 密码不能小于6位,如果小于6位则提示 “密码不能少于6位”

代码如下:


import 'package:flutter/material.dart';

class FormTestRoute extends StatefulWidget {
  const FormTestRoute({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _FormTestRouteState();
}

class _FormTestRouteState extends State<FormTestRoute> {
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final GlobalKey _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Form demo'),
        ),
        body: Form(
            key: _formKey,
            autovalidateMode: AutovalidateMode.onUserInteraction,
            child: Column(
              children: [
                TextFormField(
                  autofocus: true,
                  controller: _usernameController,
                  decoration: const InputDecoration(
                      labelText: "username",
                      hintText: "username or email",
                      icon: Icon(Icons.person)),
                  validator: (username) {
                    return username!.trim().isNotEmpty
                        ? null
                        : "username cannot empty";
                  },
                ),
                TextFormField(
                  controller: _passwordController,
                  decoration: const InputDecoration(
                      labelText: "password",
                      hintText: "please input your password",
                      icon: Icon(Icons.lock)),
                  obscureText: true,
                  validator: (pwd) {
                    return pwd!.trim().length >= 6
                        ? null
                        : "password digit cannot less than 6!";
                  },
                ),
                // login button
                Padding(
                  padding: const EdgeInsets.only(top: 28.0),
                  child: Row(
                    children: [
                      Expanded(
                          child: ElevatedButton(
                        onPressed: () {
                          if ((_formKey.currentState as FormState).validate()) {
                            print("Loing success");
                          }
                        },
                        child: const Padding(
                          padding: EdgeInsets.all(16.0),
                          child: Text("Login"),
                        ),
                      ))
                    ],
                  ),
                )
              ],
            )));
  }
}

效果如下图所示:

以上所述是小编给大家介绍的Flutter基本组件Basics Widget学习,希望对大家有所帮助。在此也非常感谢大家对编程学习网网站的支持!

本文标题为:Flutter基本组件Basics Widget学习