美文网首页Flutter圈子FlutterFlutter中文社区
Flutter布局锦囊---带彩条的文本字段

Flutter布局锦囊---带彩条的文本字段

作者: 何小有 | 来源:发表于2019-01-03 19:24 被阅读17次

    设计给的效果如下:

    UI布局图

    拿到设计后,先把整体拆分成几个部分:

    1. “文本输入框”,使用文本字段(TextField)组件实现的输入框。
    2. “状态指示条”,使用容器(Container)组件实现带颜色的长方形。

    然后就可以开始进行编码了。

    第1步:绘制组件树

    带彩条的文本字段的组件树.png

    第2步:实现“文本输入框”

    Flutter的布局代码嵌套非常深,为了代码的可读性,你可以先把一部分没有依赖的纯样式代码提取出来。

    import 'package:flutter/material.dart';
    
    // 文字样式(`TextStyle`)组件,一个不透明的对象,用于确定文本的大小,位置和呈现。
    /// 文本域(`TextField`)组件使用的样式。
    final TextStyle _textFieldStyle = TextStyle(
      // 字体大小。
      fontSize: 22.0,
      // 字母间距。
      letterSpacing: 0.78,
      // 字体系列。
      fontFamily: 'BebasNeueBold',
      // 颜色。
      color: const Color(0xFF4A4A4A),
    );
    
    /// 输入装饰(`InputDecoration`)组件的提示样式(`hintStyle`)属性值。
    final TextStyle _hintStyle = TextStyle(
      fontSize: 16.0,
      color: const Color(0xFF9B9B9B),
    );
    

    定义一下该自定义组件构建时需要的成员变量,并在默认构建函数中传递一下调用者提供的参数。

    /// 自定义的登录表单字段组件。
    class LoginFormField extends StatefulWidget {
      /// 字段内的提示文字。
      final String hintText;
      /// 文本字段的控制器。
      final TextEditingController textEditingController;
      /// 文本字段的最大长度。
      final int maxLength;
      /// 文本字段的最小长度。
      final int minLength;
      /// 文本字段长度合理时的回调函数。
      final Function legitimateCallback;
      /// 文本字段长度不合理时的回调函数。
      final Function illegalCallback;
    
      LoginFormField({
        @required
        this.hintText,
        this.textEditingController,
        this.maxLength,
        this.minLength,
        this.legitimateCallback,
        this.illegalCallback,
      });
    
      @override
      _LoginFormFieldState createState() => _LoginFormFieldState();
    }
    

    先写好一个垂直(Column)组件,接下来会在垂直(Column)组件中具体实现“文本输入框”和“状态指示条”。

    /// 与自定义的登录表单字段组件关联的状态子类。
    class _LoginFormFieldState extends State<LoginFormField> {
      /// 文本字段下方的提示颜色。
      Color inputColor;
    
      @override
      void initState() {
        super.initState();
        inputColor = Color(0xFFC5C5C5);
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            // TODO: 实现“文本输入框”。
            // TODO: 第3步:实现“状态指示条”。
          ],
        );
      }
    }
    

    通过设置文本字段(TextField)组件的属性和方法,实现UI图的效果。同时通过简单的文本长度来校验数据是否合法,当前你可以添加更多的校验逻辑,来满足业务需求。

            // TODO: 实现“文本输入框”。
            // 文本字段(`TextField`)组件,允许用户使用硬件键盘或屏幕键盘输入文本。
            TextField(
              // 控制器属性,控制正在编辑的文本。
              controller: widget.textEditingController,
              // 光标颜色属性,绘制光标时使用的颜色。
              cursorColor: const Color(0xFFFF6B47),
              // 光标宽度属性,光标的厚度,默认是2.0。
              cursorWidth: 2.0,
              // 样式属性,用于正在编辑的文本的样式。
              style: _textFieldStyle,
              // 键盘类型属性,用于编辑文本的键盘类型。
              keyboardType: TextInputType.number,
              // 装饰(`decoration`)属性,在文本字段周围显示的装饰。
              // 输入装饰(`InputDecoration`)组件。
              decoration: InputDecoration(
                // 边框属性,装饰的容器周围绘制的形状。
                border: InputBorder.none,
                // 填充属性,如果为`true`,则装饰的容器将填充fillColor颜色。
                filled: true,
                // 填充颜色属性,填充装饰容器的颜色。
                fillColor: const Color(0xFFF4F3F4),
                // 是密集属性,输入子项是否是密集形式的一部分(即使用较少的垂直空间)。
                isDense: true,
                // 提示样式属性,用于提示文本(`hintText`)的样式。
                hintStyle: _hintStyle,
                // 提示文本属性,提示字段接受哪种输入的文本。
                hintText: widget.hintText,
              ),
              // 在改变属性,当正在编辑的文本发生更改时调用。
              onChanged: (value) {
                // 当前文本字段中值的长度。
                int fieldValue = value.trim().length;
                if (fieldValue == 0) {
                  inputColor = Color(0xFFC5C5C5);
                } else if (fieldValue > widget.maxLength) {
                  inputColor = Color(0xFFFF3E44);
                } else {
                  inputColor = Color(0xFF00CED2);
                }
                setState(() {});
                // 当前文本字段中值的长度符合给定范围时调用回调函数。
                if (fieldValue > widget.minLength-1 && fieldValue < widget.maxLength+1) {
                  widget.legitimateCallback();
                } else {
                  widget.illegalCallback();
                }
              },
            ),
    

    第3步:实现“状态指示条”

    最后使用容器(Container)组件实现2条简单的带颜色的长方形。

            // TODO: 第3步:实现“状态指示条”。
            Container(
              height: 2.0,
              color: const Color(0xFF242406),
            ),
            Container(
              height: 2.0,
              color: inputColor,
            ),
    

    第4步:还原效果

    带彩条的文本字段的还原效果

    相关文章

      网友评论

        本文标题:Flutter布局锦囊---带彩条的文本字段

        本文链接:https://www.haomeiwen.com/subject/zbxqrqtx.html