美文网首页
TextField封装实践 2023-08-01 周二

TextField封装实践 2023-08-01 周二

作者: 勇往直前888 | 来源:发表于2023-08-05 11:23 被阅读0次

简介

文本输入框,这个是不可避免需要使用的。比如像这样的搜索框

企业微信截图_2d33ba12-b3cd-4d86-ad28-f7e4f07fb355.png

组件选择

  • 一种是安卓风格的TextField

  • 另外一种是iOS风格的CupertinoTextField

一开始因为熟悉,我们选择了CupertinoTextField,并且有输入内容的时候会自动显示删除按钮,非常方便。只是后来,UI要求删除按钮的图标要换,没有办法,只能换成TextField

属性设置

  • 由于需要更新状态,所以选择了StatefulWidget;一开始的想法是引入GetX,不过后来想想,将GetX引入组件不大合适

  • TextEditingController肯定要一个的。如果外部给了,那么就用外部的;如果没有,内部自己生成一个。

/// 初始化控制器
_controller = widget.controller ?? TextEditingController();
  • FocusNode内部自己生产一个,需要监控焦点。得到焦点显示删除按钮,失去焦点隐藏删除按钮。
    /// 焦点监控
    _focusNode.addListener(() {
      LogUtil.log("Has focus: ${_focusNode.hasFocus}");

      setState(() {
        if (_focusNode.hasFocus) {
          _isShowDelete = true;
        } else {
          _isShowDelete = false;
        }
      });
    });
  • 由于图标和输入区的间距也有要求,所以prefixsuffix等属性都不用,直接放入一个Row之中进行自定义。

  • 由于TextField的属性实在太多,所以根据UI给的样式设置一个,其他的属性全部屏蔽,减少使用难度。

  • 对外提供只需要以下几个必要的参数就可以了,其他的样式内部写死就可以了。TextField属性太多,使用起来很不方便,在一个地方封装一下就可以了。

  final TextEditingController? controller;
  final String? placeholder;
  final void Function(String)? onChanged;
  final void Function(String)? onSubmitted;

参考代码

不能copy使用,仅能做参考

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:pandabuy/r.dart';
import 'package:pandabuy/theme/panda_color_config.dart';
import 'package:pandabuy/utils/log_util.dart';

class SearchWidget extends StatefulWidget {
  const SearchWidget({
    Key? key,
    this.controller,
    this.placeholder,
    this.onChanged,
    this.onSubmitted,
  }) : super(key: key);

  final TextEditingController? controller;
  final String? placeholder;
  final void Function(String)? onChanged;
  final void Function(String)? onSubmitted;

  @override
  State<SearchWidget> createState() => SearchWidgetState();
}

class SearchWidgetState extends State<SearchWidget> {
  late TextEditingController _controller;
  final _focusNode = FocusNode();
  bool _isShowDelete = false;

  @override
  void initState() {
    super.initState();

    /// 初始化控制器
    _controller = widget.controller ?? TextEditingController();

    /// 焦点监控
    _focusNode.addListener(() {
      LogUtil.log("Has focus: ${_focusNode.hasFocus}");

      setState(() {
        if (_focusNode.hasFocus) {
          _isShowDelete = true;
        } else {
          _isShowDelete = false;
        }
      });
    });
  }

  @override
  void dispose() {
    /// 销毁控制器
    _focusNode.dispose();
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 32.h,
      margin: EdgeInsets.only(left: 5.w),
      decoration: BoxDecoration(
        color: PandaColorConfig().backgroundF5F5F5,
        borderRadius: BorderRadius.circular(16.h),
      ),
      child: Row(
        children: [
          Container(
            margin: EdgeInsets.only(left: 15.w, right: 5.w),
            child: Image.asset(
              R.assetsImg44Search,
              width: 18,
              height: 18,
              fit: BoxFit.contain,
            ),
          ),
          Expanded(
            child: Center(
              child: TextField(
                controller: _controller,
                focusNode: _focusNode,
                cursorColor: PandaColorConfig().background11BA66Both,
                textInputAction: TextInputAction.search,
                style: TextStyle(
                  color: PandaColorConfig().text333333,
                  fontSize: 14.sp,
                  fontWeight: FontWeight.w400,
                ),
                decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: widget.placeholder ?? 'Name/OrderNo./ItemNo.'.tr,
                  hintStyle: TextStyle(
                    color: PandaColorConfig().text999999,
                    fontSize: 14.sp,
                    fontWeight: FontWeight.w400,
                  ),
                  isCollapsed: true,
                ),
                onChanged: widget.onChanged,
                onSubmitted: widget.onSubmitted,
              ),
            ),
          ),
          Visibility(
            visible: _isShowDelete,
            child: GestureDetector(
              onTap: () {
                setState(() {
                  _controller.clear();
                });
              },
              child: Container(
                margin: EdgeInsets.only(left: 5.w, right: 15.w),
                child: Image.asset(
                  R.assetsImgTagDelete,
                  width: 12,
                  height: 12,
                  fit: BoxFit.contain,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

相关文章

  • TextField整体封装

    作为一个iOS长久开发人员来说 ,也接触了很多项目,聪明的你会发现 ,有很多项目重复的代码,为了代码的简洁,不会每...

  • 封装Label,TextField

    1.创建UIView2.在UIView.h中创建两个属性 3.在UIView.m中重写初始化方法.创建新方法 4....

  • 基于 IOS:OC控件---封装代码的两种方法

    一首先我们把要封装的控件封装到 UIView上;在这里我们先封装label和textfield1创建UIView的...

  • Reflection

    Reflection 反射实践之数据封装

  • iOS网络框架简单封装

    AFN 简单封装--iOS重构-轻量级的网络请求封装实践 YTKNetworking 网络框架封装源码解析:网络层...

  • 2023-08-01

    万里长江山百仞, 流芳叠翠塔为峰。 浮云恋恋随帆影, 渡客遥听大圣钟。 注: 渡客:鉴真法师,东渡曾经过狼山 大圣...

  • 2023-08-01

    心理学上有个著名的“踢猫效应”: 一位父亲,因为在公司受到老板批评,而心烦气燥。回到家,他看到孩子在沙发上跳来跳去...

  • UITextField - OC

    textField textField定义 textField初始化 textField 的位置设置 textFi...

  • UITextField(键盘弹出和回收)

    当前view结束编辑,回收键盘。这个方法适用于textField或者textView较多的情况下,也可封装在所有页...

  • IOS中TextField中支付只能输入数字,并且小数点后最多输

    IOS中TextField中支付只能输入数字,并且小数点后最多输入两位 标签(空格分隔): 常用封装 IOS实现方...

网友评论

      本文标题:TextField封装实践 2023-08-01 周二

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