Flutter 3 基础10: 监听文本框的内容变化

在[上一篇文章]中,我们学习了如何获取用户在文本框中输入的内容,以及如何把一个无状态部件转换为有状态部件。

在有些场景下,我们除了获取文本框的内容,还需要把文本框输入的内容与其他部件进行联动显示,或者实时校验用户输入的每一个字符是否合规。这时候,我们需要监听文本框内容的变化。

启动 Android Studio,打开 hello_world 项目,运行虚拟机,这样就可以实时看到编码产生的效果。现在,我们的部件页面展示了文本框和按钮两个部件。

监听文本框内容变化

  1. lib/widget 文件夹下,打开 my_widgets.dart 文件,定位到下列代码:
dart 复制代码
final _textController = TextEditingController();

在这一行代码的下面,添加如下代码:

dart 复制代码
 _nameController.addListener(() {
    setState(() {
      _name = _nameController.text;
    });
  });
  1. 热重启项目。点击部件导航图标,在页面的文本框中输入一些内容,例如,1234567.
  1. 查看控制台输出,可以看到,我们获取到了用户在文本框中输入的内容。
  1. 删除文本框中的内容,也会获得同样的效果。

重构文本框代码

观察 my_widgets.dart 文件中 build 方法的代码:

dart 复制代码
@override  
Widget build(BuildContext context) {  
  return Column(  
    children: [  
      TextField(  
        controller: _textController,  
        decoration: const InputDecoration(  
            border: OutlineInputBorder(),  
            hintText: "请输入一些文字。"),  
      ),  
      MaterialButton(  
        textColor: Colors.white,  
        color: Colors.green,  
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),  
        onPressed: () {  
          print(_textController.text);  
        },  
        child: const Text('显示'),  
      )  
    ],  
  );

如果我们继续添加新的部件,这个方法会变得臃肿起来,不利于阅读和维护。现在我们来进行重构。

  1. 继续在 my_widgets.dart 文件中,定位到下列代码:
dart 复制代码
TextField(  
  controller: _textController,  
  decoration: const InputDecoration(  
      border: OutlineInputBorder(),  
      hintText: "请输入一些文字。"),  
)
  1. 选中这一块代码,点击鼠标右键,一次选择 Refactor > Extract Method...:

注意:不要选中语句结尾的逗号 ,.

  1. 在弹出的对话框中,输入方法的名称,这里我们默认提供的方法名称,点击 Refactor 按钮:
  1. Android Studio 会自动为我们生成一个方法:
dart 复制代码
TextField buildTextField() {  
  return TextField(  
      controller: _textController,  
      decoration: const InputDecoration(  
          border: OutlineInputBorder(),  
          hintText: "请输入一些文字。"),  
    );  
}

同时,也自动把原来使用的代码替换为新方法的调用:

dart 复制代码
@override  
Widget build(BuildContext context) {  
  return Column(  
    children: [  
      buildTextField(),
      MaterialButton(  
        textColor: Colors.white,  
        color: Colors.green,  
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),  
        onPressed: () {  
          print(_textController.text);  
        },  
        child: const Text('显示'),  
      )  
    ],  
  );  
}

重构按钮代码

使用同样的办法,重构 my_widgets.dart 文件中的下列代码:

dart 复制代码
MaterialButton(  
  textColor: Colors.white,  
  color: Colors.green,  
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),  
  onPressed: () {  
    print(_textController.text);  
  },  
  child: const Text('显示'),  
)

Android Studio 会自动为我们生成一个创建按钮的新方法:

dart 复制代码
MaterialButton buildMaterialButton() {  
  return MaterialButton(  
      textColor: Colors.white,  
      color: Colors.green,  
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),  
      onPressed: () {  
        print(_textController.text);  
      },  
      child: const Text('显示'),  
    );  
}

而且,我们的 build 方法也变得整洁了许多。

dart 复制代码
@override
Widget build(BuildContext context) {
  return Column(
    children: [
      buildTextField(),
      buildMaterialButton()
    ],
  );
}

提交代码

我们已经实现了文本框内容变化监听的处理功能,又到达了一个小小的里程碑,应该对代码进行提交,保持良好编程习惯。

shell 复制代码
git add .
git commit -m '监听文本框内容变化并重构一些代码。'
相关推荐
过期的H2O212 分钟前
【H2O2|全栈】关于CSS(4)CSS基础(四)
前端·css
纳尼亚awsl25 分钟前
无限滚动组件封装(vue+vant)
前端·javascript·vue.js
八了个戒31 分钟前
【TypeScript入坑】TypeScript 的复杂类型「Interface 接口、class类、Enum枚举、Generics泛型、类型断言」
开发语言·前端·javascript·面试·typescript
西瓜本瓜@33 分钟前
React + React Image支持图像的各种转换,如圆形、模糊等效果吗?
前端·react.js·前端框架
黄毛火烧雪下34 分钟前
React 的 useEffect 钩子,执行一些异步操作来加载基本信息
前端·chrome·react.js
蓝莓味柯基39 分钟前
React——点击事件函数调用问题
前端·javascript·react.js
资深前端之路40 分钟前
react jsx
前端·react.js·前端框架
cc蒲公英1 小时前
vue2中使用vue-office库预览pdf /docx/excel文件
前端·vue.js
Sam90291 小时前
【Webpack--013】SourceMap源码映射设置
前端·webpack·node.js
小兔崽子去哪了1 小时前
Element plus 图片手动上传与回显
前端·javascript·vue.js