Flutter中无法更新List或Map内Widget的状态如何解决
问题原因
这个问题是Flutter的Widget构建机制和缓存逻辑冲突导致的:
- 存到
fieldsMap里的TextField是在initState生命周期里通过addFields()创建的,创建时就把当时初始的绿色problemColor写死到了Widget的配置里,这个实例创建完就一直存在Map中,不会自动更新内部属性。 - 你调用
setState修改problemColor时,Flutter只会重新执行build方法刷新组件树,但你从Map里取出的还是初始化时创建的那个旧TextField实例,它的填充色从创建后就没被修改过,自然不会变成红色。 - 直接写在组件树里的TextField能正常变色,是因为每次
build执行时它都会被重新创建,自动读取最新的noProblemColor值,所以能响应状态变化。
修复方法
不要提前创建并缓存Widget实例,你需要存储的是控制UI的状态数据,而不是Widget本身。Widget本身是每次build时临时生成的界面配置,不需要手动缓存,Flutter框架已经做了对应的性能优化。
原来的initState和预创建Widget的addFields逻辑可以直接删除,修复后的核心代码如下:
class _MyHomePageState extends State<MyHomePage> { // 仅存储颜色状态,不再缓存TextField组件 final Map<int, Color> fieldStatus = {0: const Color(0xff4caf50)}; Color noProblemColor = const Color(0xff4caf50); @override Widget build(BuildContext context) { print('field color 0 = ${fieldStatus[0]}'); print('noProblemColor = $noProblemColor'); return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ // 每次build时动态生成TextField,自动读取最新的颜色值 TextField( decoration: InputDecoration(filled: true, fillColor: fieldStatus[0]), onChanged: ((val) { setState(() { fieldStatus[0] = const Color(0xfff44336); }); }), ), TextField( decoration: InputDecoration(filled: true, fillColor: noProblemColor), onChanged: ((val) { setState(() { noProblemColor = const Color(0xfff44336); }); }), ) ], ), ), ); } }
补充:Flutter里的Widget是不可变的,不要把Widget当作持久化的状态载体存储,你只需要维护好控制UI的状态(比如这里的颜色值、输入内容等),在build方法里根据当前状态生成对应Widget即可。
内容的提问来源于stack exchange,提问作者Danny Hirmiz
相关产品推荐
相关产品推荐

