Flutter 自己封装TextField,导致在列表中数据更新时,数据显示错乱问题。

需求

有一个可输入的列表,输入列表会根据选择的选项不同,而输入不同内容。

比如:

选择 Vip客户时,需要输入:姓名,手机号,住址,Vip时长,付款方式

选择普通用户时,需要输入:姓名,手机号,住址。

实现

使用ListView展示所有的输入项,因为输入框具有通用性。所以做了一个简单的封装。

左侧为标题,右侧为输入内容,空内容时,展示hint提示请输入

大概是这样的样式

-----------------------------
客户类型             ⊙Vip ⊙普通
-----------------------------
姓名                     请输入
-----------------------------
手机号                   请输入
-----------------------------
住址                     请输入
-----------------------------

当客户类型改变时,下方数据需要联动改变。

问题

切换客户类型时,会有数据错乱的情况(比如手机号显示到了姓名那里)。

追查问题:

由于数据共享使用的Provider+ChangeNotifier的形式。所以,数据变化时,实际上,引用到了值得地方会进行更新的。

所以第一步判断,值是否传递到了自己封装的组件中。

自己封装的输入框代码(简陋版,主要为了说明问题):

// CustomInputTextField

class CustomInputTextField extends StatefulWidget {
	// 提示
	final String hint;
  // 输入变化监听
  final ValueChanged<String>? onValueChanged;	
  // 初始值
  final String? value;
  
  const CustomInputTextField(
      {Key? key,
      required this.hint,
      this.onValueChanged,
      this.value,})
      : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return CustomInputTextFieldState();
  }
}

class CustomInputTextFieldState extends State<CustomInputTextField> {

	late TextEditingController _controller;
	@override
	void initState() {
		_controller = TextEditingController(text : widget.value??"");
	}

	@override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      onChanged: onInputChanged,
    );
  }
}

发现问题原因

其实,当数据更新时,每次Build时拿到的值是正确的值,那为什么,显示出来的值确实错乱的呢?

因为,TextField中的值,显示的其实是_controller中的Text,而因为使用了State,而initState方法只会执行一次,所以当组件中value变化时候,实际上,_controller中的数据并没有变化。所以显示的会错乱。

解决方案

粗暴版

直接每次都创建新的controller,因为这个controller在整个组件中,没有主动用到。

controller: TextEditingController.fromValue(
        TextEditingValue(
          text: widget.value??'',
          selection: TextSelection.fromPosition(
            TextPosition(offset: widget.value?.length ?? 0),
          ),
        ),
      ),
善良版
在每次组件调用didChangeDependence时,重新取widget的值给_controller赋值上。

或者在didUpdateWidget时,将新的值拿到,与旧的值对比,并替换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值