当前位置:首页 > 数码 > 事件-5条规则-Flutter-中的-脱颖而出的-onTap (事件分为哪五类)

事件-5条规则-Flutter-中的-脱颖而出的-onTap (事件分为哪五类)

admin3个月前 (04-29)数码18

小细节决定了你的熟练程度,这些小细节的有趣之处在于它们的丰富性。您将在代码库中的数百个位置遇到 onTap 事件。增强它们可以对代码的可维护性和最终用户体验产生重大的积极影响。就是这样一个微小但丰富的东西——我们在每个屏幕上都使用它。这纯粹是关于那些 onTap 事件:该做和不该做。

规则 1:小部件不应实现 onTap 逻辑

顾名思义,小部件是在屏幕上绘制的一块 UI,它应该对业务逻辑一无所知。如果需要,它可以将事件传递给其父级。做到这一点的最佳方法是使用函数作为构造函数参数。

    // 不要做
    class MyWidget extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            debugPrint(MyWidgetonTap called);
            fetchFromServer();
          },
          child: Container(
            width: 100,
            height: 100,
            color: Colors.orange,
          ),
        );
      }
    }
  
    // 要做
    class MyWidget extends StatelessWidget {
      const MyWidget({this.onTap});
      final void Function()? onTap;

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.orange,
          ),
        );
      }
    }
  

规则 2:onTap 函数应该可为 null

作为 UI 的一部分,小部件应该是可重用的。不同的用例可能需要也可能不需要其 onTap 功能。因为它存在的主要原因是在屏幕上绘制而不是向其父级或控制器发送事件,所以它应该能够在有或没有 onTap 事件的情况下存在。

    // 不要做
    class MyWidget extends StatelessWidget {
      const MyWidget({required this.onTap});
      final void Function() onTap;

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Container(...),
        );
      }
    }
  
    // 要做
    class MyWidget extends StatelessWidget {
      const MyWidget({this.onTap});
      final void Function()? onTap;

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Container(...),
        );
      }
    }
  

规则 3:UI 必须对逻辑一无所知,即使是指示性意义上的也不行

即使在使用最佳实践之后,一个常见的错误是命名指示业务逻辑的 UI 事件函数。银行应用程序中的小部件应该不知道它属于银行应用程序,并且只有足够的数据来绘制它自己和它的孩子。换句话说,一个小部件应该是美丽而愚蠢的。

    // 不要做
    class MyScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: MyWidget(
            onTap: controller.fetchData,
          ),
        );
      }
    }
  
    // 要做
    class MyScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: MyWidget(
            onTap: () {
              // 触发一些业务逻辑
            },
          ),
        );
      }
    }
  

结论

遵循这些规则可以帮助您创建更易于维护和可重用的 UI。它们还可以提高最终用户体验,因为它们将使您的应用程序更加响应和直观。


Flutter TextField 文本输入框的基本属性及详解

源码分析:

分析源码可得,TextField 是有状态 StatefulWidget,有丰富的属性,自定义化较高,实践中需要合理利用各种回调;

1、光标的相关属性;cursorColor 为光标颜色,cursorWidth 为光标宽度,cursorRadius 为光标圆角;其中 Radius 提供了 circle 圆角和 elliptical 非圆角两种;

2、textAlign 为文字起始位置,可根据业务光标居左/居右/居中等;注意只是文字开始方向;textDirection 问文字内容方向,从左向右或从右向左;

3、maxLength 为字符长度,设置时默认是展示一行,且右下角有编辑长度与整体长度对比;与 maxLengthEnforced 配合,maxLengthEnforced 为 true 时达到最大字符长度后不可编辑;为 false 时可继续编辑展示有差别;

4、设置 maxLength 之后右下角默认有字符计数器,设置 即可只展示输入字符数;

5、maxLines 为允许展现的最大行数,在使用 maxLength 时内容超过一行不会自动换行,因为默认 maxLines=1,此时设置为 null 或固定展示行数即可自动换行;区别在于 null 会展示多行,而 maxLines 最多只展示到设置行数;

6、obscureText 是否隐藏编辑内容,常见的密码格式;

7、enableInteractiveSelection 长按是否出现【剪切/复制/粘贴】菜单;不可为空;

8、keyboardAppearance 为键盘亮度,包括 /light 两种,但仅限于 iOS 设备;

5条规则

9、textCapitalization 文字大小写;理论上 sentences 为每句话第一个字母大写;characters为每个字母大写;words 为每个单词首字母大写;但该属性仅限于 text keybord,和尚在本地更换多种方式并未实现,有待研究;

10、keyboardType 为键盘类型,和尚理解整体分为数字键盘和字母键盘等;根据设置的键盘类型,键盘会有差别;

a. 数字键盘 --1-- datetime 键盘上可随时访问 : 和 /; --2-- phone 键盘上可随时访问 # 和 *; --3-- number 键盘上可随时访问 + - * /

b. 字母键盘 --1-- emailAddress 键盘上可随时访问 @ 和 .; --2-- url 键盘上可随时访问 / 和 .; --3-- multiline 适用于多行文本换行; --4-- text 默认字母键盘;

11、textInputAction 通常为键盘右下角操作类型,类型众多,建议多多尝试;

12、autofocus 是否自动获取焦点,进入页面优先获取焦点,并弹出键盘,若页面中有多个 TextField 设置 autofocus 为 true 则优先获取第一个焦点;

13、focusNode 手动获取焦点,可配合键盘输入等减少用户操作次数,直接获取下一个 TextField 焦点;

14、enabled 设为 false 之后 TextField 为不可编辑状态;

15、decoration 为边框修饰,可以借此来调整 TextField 展示效果;可以设置前置图标,后置图片,边框属性,内容属性等,会在后续集中尝试;若要完全删除装饰,将 decoration 设置为空即可;

16、inputFormatters 为格式验证,例如原生 Android 中通常会限制输入手机号或其他特殊字符,在 Flutter 中也可以借此来进行格式限制,包括正则表达式;使用时需要引入 package:flutter/;

a. LengthLimitingTextInputFormatter 限制最长字符;

b. WhitelistingTextInputFormatter 仅允许输入白名单中字符;如 digitsOnly 仅支持数字 [0-9];

c. BlacklistingTextInputFormatter 防止输入黑名单中字符;如 singleLineFormatter 强制输入单行; 分析源码 RegExp([/]) 可以设置正则表达式;

17、onChanged 文本内容变更时回调,可实时监听 TextField 输入内容;

18、controller 文本控制器,监听输入内容回调;

19、onTap 点击 TextField时回调;

20、onEditingComplete 在提交内容时回调,通常是点击回车按键时回调;

21、onSubmit 在提交时回调,不可与 onEditingComplete 同时使用,区别在于 onSubmit 是带返回值的回调;

问题小结:

当 TextField 设置 enableInteractiveSelection 属性后长按会出现菜单,默认为英文,可通过设置 Flutter 国际化来处理;

(1)在 中集成 flutter_localizations;

2)在 MaterialApp 中设置本地化代理和支持的语言类型;

(1)将 maxLength 设置为 null 仅使用 LengthLimitingTextInputFormatter 限制最长字符;

(2)设置 InputDecoration 中 decoration属性为空;但是底部有空余,只是隐藏而并非消失;

麻烦各位大神指点一下怎样用flutter写出一个首页?

针对中间的图片按钮,可以使用Wrap,或者两个Row。想要让图片有点击响应,需要在外层套一个InkWell。

参考样式:

参考代码:

Wrap(alignment: ,children: [_imageButton(),_imageButton(),_imageButton(),_imageButton(),],)

///_imageButton

_imageButton() {return Container(margin: (10),decoration: BoxDecoration(border: (color: ,width: 1,),),width: 180,height: 180,child: InkWell(onTap: (){debugPrint(点到了);},child: (}

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Flutter