iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Flutter 如何封装文本输入框组件
  • 967
分享到

Flutter 如何封装文本输入框组件

2024-04-02 19:04:59 967人浏览 八月长安
摘要

目录UI组件封装的考虑要点文本输入框接口定义代码实现组件使用踩坑记录总结UI组件封装的考虑要点 封装一个 UI 组件,通常需要考虑下面这三个点: 接口如何定义:即组件接收

UI组件封装的考虑要点

封装一个 UI 组件,通常需要考虑下面这三个点:

  1. 接口如何定义:即组件接收什么输入参数来控制组件的外观和行为;
  2. 与业务分离:UI 组件应当只负责界面,而不负责业务,具体的业务应当由业务层完成;
  3. 简单易用:因为是 UI 组件,要尽可能地简单易用,方便使用者快速上手。

文本输入框接口定义

首先先看一下我们上一篇使用文本框的代码,这里实际上只是调用了一个函数返回新的组件,之所以要这么做是因为用户名、密码使用了成员属性,需要根据不同的成员属性来设置不同的行为,主要有:

  • 文本框装饰不同:包括占位符、前置图标,后置图标的行为绑定了成员属性以及不同的 TextEditinGCongtroller。
  • onChanged 事件回调内容不同。
  • 键盘类型和是否隐藏输入内容不同。
  • 对应表单的字段不同。

Widget _getPassWordInput() {
    return _getInputTextField(
      TextInputType.text,
      obscureText: true,
      controller: _passwordController,
      decoration: InputDecoration(
        hintText: "输入密码",
        icon: Icon(
          Icons.lock_open,
          size: 20.0,
        ),
        suffixIcon: GestureDetector(
          child: Offstage(
            child: Icon(Icons.clear),
            offstage: _password == '',
          ),
          onTap: () {
            this.setState(() {
              _password = '';
              _passwordController.clear();
            });
          },
        ),
        border: InputBorder.none,
      ),
      onChanged: (value) {
        this.setState(() {
          _password = value;
        });
      },
    );
  }

而实际造成差别的原因是成员属性之间的差异不同,如果是继续使用成员属性这种方式,无法解决这个问题。这时候我们可以考虑把整个表单放入一个 Map 中,Map里配置不同字段对应的差异化属性,然后就可以做到通用的接口了,我们可以定义封装后的组件接口:


Widget _getInputTextFieldNew(
    String fORMKey,
    String value, {
    TextInputType keyboardType = TextInputType.text,
    Focusnode focusNode,
    controller: TextEditingController,
    onChanged: Function,
    String hintText,
    IconData prefixIcon,
    onClear: Function,
    bool obscureText = false,
    height = 50.0,
    margin = 10.0,
  }) {
  //......
}

新增的参数如下:

  • formKey:表示文本框对应的是表单Map的哪个键;
  • value:当前表单的值,用于控制是否显示清除按钮
  • onClear:定义右侧清除按钮的行为响应
  • onChanged:输入内容变比回调

代码实现

抽离后的代码与业务页面无关,因此需要抽离代码,在 lib 目录下新增一个 components 目录,增加一个 form_util.dart 文件,用于存放通用的表单组件。实现的代码如下所示:


class FormUtil {
  static Widget textField(
    String formKey,
    String value, {
    TextInputType keyboardType = TextInputType.text,
    FocusNode focusNode,
    controller: TextEditingController,
    onChanged: Function,
    String hintText,
    IconData prefixIcon,
    onClear: Function,
    bool obscureText = false,
    height = 50.0,
    margin = 10.0,
  }) {
    return Container(
      height: height,
      margin: EdgeInsets.all(margin),
      child: Column(
        children: [
          TextField(
              keyboardType: keyboardType,
              focusNode: focusNode,
              obscureText: obscureText,
              controller: controller,
              decoration: InputDecoration(
                hintText: hintText,
                icon: Icon(
                  prefixIcon,
                  size: 20.0,
                ),
                border: InputBorder.none,
                suffixIcon: GestureDetector(
                  child: Offstage(
                    child: Icon(Icons.clear),
                    offstage: value == null || value == '',
                  ),
                  onTap: () {
                    onClear(formKey);
                  },
                ),
              ),
              onChanged: (value) {
                onChanged(formKey, value);
              }),
          Divider(
            height: 1.0,
            color: Colors.grey[400],
          ),
        ],
      ),
    );
  }
}

组件使用

首先是使用 Map 定义当前页面的表单内容,以便控制不同表单字段的呈现形式。


Map<String, Map<String, Object>> _formData = {
    'username': {
      'value': '',
      'controller': TextEditingController(),
      'obsecure': false,
    },
    'password': {
      'value': '',
      'controller': TextEditingController(),
      'obsecure': true,
    },
  };

其次是定义统一的文本框 onChanged 和 onClear 方法,对应为 _handleTextFieldChanged和_handleClear。通过 formKey 回传的字段,可以更新对应 _formData 的内容。这里注意使用了 as用法用于将一个 Object 转换为TextEditingController。这种转换如果 Object 对应的类型是TextEditingController的话能够成功转换,也能正常执行后面的 clear()方法。但是如果是 null,直接这时候执行 clear()方法,会报空指针异常。因此在转换结果后面加了个问号,这个表示是如果是 null 后面的方法不会执行,从而不会出现空指针异常。这是 Flutter 2.0引入的 null safety 特性。其实这个特效在 PHP 7,Swift 语言早就有应用了。


_handleTextFieldChanged(String formKey, String value) {
    this.setState(() {
      _formData[formKey]['value'] = value;
    });
  }

  _handleClear(String formKey) {
    this.setState(() {
      _formData[formKey]['value'] = '';
      (_formData[formKey]['controller'] as TextEditingController)?.clear();
    });
  }

之后是在使用 textField 的地方使用 FormUtil.textField 方法直接使用封装好的文本框:


//...
FormUtil.textField(
    'username',
    _formData['username']['value'],
    controller: _formData['username']['controller'],
    hintText: '请输入手机号',
    prefixIcon: Icons.mobile_friendly,
    onChanged: _handleTextFieldChanged,
    onClear: _handleClear,
  ),
FormUtil.textField(
    'password',
    _formData['password']['value'],
    controller: _formData['password']['controller'],
    obscureText: true,
    hintText: '请输入密码',
    prefixIcon: Icons.lock_open,
    onChanged: _handleTextFieldChanged,
    onClear: _handleClear,
),
//...

可以看到,username和 password 两个表单字段复用了_handleTextFieldChanged和_handleClear。整个代码长度也减少了近50%,而且封装的 FormUtil.textField 文本框也可以用于其他表单页面,整个代码的维护性和复用性都相比前一篇的有了很大的提高。

踩坑记录

在封装 文本框的时候,直接将 onClear 函数复制给了GesureDetector 的 onTap 属性,结果每次输入都会触发 onClear自动清空文本框内容。后来发现实际应该是传一个回调函数,下面列出了两种方式的不同:


//...
//错误的方式
onTap:onClear,
//...

//...
//正确的方式
onTap:() {
  onClear(formKey);
},
//...

总结

封装UI 组件在实际开发过程中非常常见,一般来说当我们看到设计稿的时候,首先是将设计稿拆分成多个组件,然后考虑一下其中的一些组件是不是在其他场合也会用到。如果有可能用到,就可以考虑封装。封装的时候先考虑对外接口参数,然后注意UI 组件不应该涉及到业务,再就是尽可能地简便(比如有一些默认值,减少必传参数)。当然,如果公司在一开始就能够由产品、设计和开发一起定一套组件,提前封装将会使得后面的开发效率更高,但这取决于项目时间的紧急程度,时间充裕的话可以这么考虑。

以上就是Flutter 如何封装文本输入框的详细内容,更多关于Flutter 封装文本输入框的资料请关注编程网其它相关文章!

--结束END--

本文标题: Flutter 如何封装文本输入框组件

本文链接: https://www.lsjlt.com/news/127634.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Flutter 如何封装文本输入框组件
    目录UI组件封装的考虑要点文本输入框接口定义代码实现组件使用踩坑记录总结UI组件封装的考虑要点 封装一个 UI 组件,通常需要考虑下面这三个点: 接口如何定义:即组件接收...
    99+
    2024-04-02
  • Vue组件封装之input输入框实战记录
    目录实战目的实战效果核心思想一 格式规范二 给父组件传递value值三 错误提示四 格式检验五 多个input框的检验写在最后实战目的 封装一个自定义的input组件,只适用于 in...
    99+
    2022-11-13
    vue input组件封装 vue封装组件思路 vue组件的封装
  • Flutter 极简 Dio 组件二次封装文档
    Flutter Dio 组件二次封装文档 前言一、添加依赖二、创建封装类三、使用封装类四、拦截器五、错误处理总结 前言 本文档介绍了如何通过二次封装 Flutter Dio 组件来简化网络请求的过程。通过封装,我们可以提高代码...
    99+
    2023-08-17
    flutter android
  • angular2如何封装material2对话框组件
    这篇文章主要介绍angular2如何封装material2对话框组件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 说明angular-material2自身文档不详,控件不齐,...
    99+
    2024-04-02
  • css如何让文本垂直对齐文本输入框
    这篇文章给大家分享的是有关css如何让文本垂直对齐文本输入框的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体方法如下input{vertical-align:middle;}css的选择器有哪些css的选择器可...
    99+
    2023-06-17
  • useState文本框无法输入如何解决
    这篇文章主要介绍“useState文本框无法输入如何解决”,在日常操作中,相信很多人在useState文本框无法输入如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”useState文本框无法输入如何解决...
    99+
    2023-07-05
  • win11文本框无法输入如何解决
    本篇内容主要讲解“win11文本框无法输入如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“win11文本框无法输入如何解决”吧!解决方法:方法一:首先确认自己选中了文本框。选中后,会有图示...
    99+
    2023-07-02
  • vue如何封装div框选时间的组件
    这篇文章主要为大家展示了“vue如何封装div框选时间的组件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue如何封装div框选时间的组件”这篇文章吧。div...
    99+
    2024-04-02
  • 跨端开发框架avm组件如何封装
    本文小编为大家详细介绍“跨端开发框架avm组件如何封装”,内容详细,步骤清晰,细节处理妥当,希望这篇“跨端开发框架avm组件如何封装”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。引言avm.js 是一个跨端开发框...
    99+
    2023-07-02
  • vue组件如何封装
    封装vue组件的方法:1.新建vue.js项目;2.使用Vue.extend()方法创建组件;3.使用Vue.component()方法注册组件;4.构建组件变量;5.使用组件名称标签调用组件;具体步骤如下:首先,在vue-cli中创建一个...
    99+
    2024-04-02
  • Angular封装WangEditor富文本组件的方法
    富文本组件是web程序中很常用的一个组件,特别是要开发一个博客,论坛这类的网站后台。 得益于Angular的强大,封装WangEditor组件非常简单 1.使用yarn或者npm...
    99+
    2024-04-02
  • vue2封装input组件方式(输入的双向绑定)
    目录vue2封装input组件重点vue二次封装input的几种方式封装原生input封装el-inputVUE高级用法封装input总结vue2封装input组件 重点 首先我们要...
    99+
    2023-05-17
    vue2封装input 封装input组件 输入的双向绑定
  • 基于element UI input组件自行封装“数字区间”输入框组件的问题及解决
    目录问题描述实现效果实现代码 问题描述 在开发时遇到一个数字区间输入框的需求,如下图: 项目使用的是vue,组件库用的是element UI,但是element UI并没有提供数字...
    99+
    2024-04-02
  • vue.js基于ElementUI如何封装CRUD的弹框组件
    本文小编为大家详细介绍“vue.js基于ElementUI如何封装CRUD的弹框组件”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue.js基于ElementUI如何封装CRUD的弹框组件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢...
    99+
    2023-07-02
  • Android如何自定义输入文本对话框?
    文章目录 0.引言1.创建示例工程2.输入文本对话框布局和功能设计3.主程序调用输入文本对话框 0.引言   笔者研究的课题涉及到安卓软件开发,在开发过程中,发现普通的显示消息对话框一般可...
    99+
    2023-10-26
    android java android studio
  • vue如何封装TabBar组件
    这篇文章主要为大家展示了“vue如何封装TabBar组件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue如何封装TabBar组件”这篇文章吧。实现思路:步骤一:TabBar和TabBarIt...
    99+
    2023-06-25
  • vue3如何封装Notification组件
    这篇文章给大家分享的是有关vue3如何封装Notification组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。弹窗组件的思路基本一致:向body插入一段HTML。我将从创建、插入、移除这三个方面来说我的做法...
    99+
    2023-06-29
  • javascript如何设置文本框不能输入数字
    本篇内容介绍了“javascript如何设置文本框不能输入数字”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2024-04-02
  • 基于element UI input组件自行封装数字区间输入框组件的问题怎么解决
    今天小编给大家分享一下基于element UI input组件自行封装数字区间输入框组件的问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这...
    99+
    2023-06-30
  • Flutter如何支持放大镜的输入框功能
    这篇文章将为大家详细讲解有关Flutter如何支持放大镜的输入框功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。功能需求最近需求开发中遇到一个Flutter开发问题,为了优化用户输入体验。产品同学希望能...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作