Flutter点击单个Container时全部容器变色问题排查解决
问题根因
- 变量作用域错误:你在
ListView.builder的itemBuilder中定义了局部变量gettw,每次循环构建单个Container时这个变量都会重新初始化,点击时修改的仅为当前迭代周期的临时变量,setState触发页面重新构建后,所有临时变量都会被重置,状态无法持久保存。 - 没有独立存储每个容器的状态:你当前的
tile数组没有为每个下标的Container单独存储颜色状态,所有容器共用一套判断逻辑,自然会出现颜色同步修改的问题。
修复方案
- 调整
tile数组的用途,直接用它存储每个下标对应Container的颜色状态,不需要额外定义gettw变量。 - 点击事件中直接修改当前点击下标对应的
tile值,触发刷新后直接从tile中读取对应状态渲染颜色即可。
如果你需要保留原来的二维
tile数组结构,只需要将下述代码中对tile[index]的读写改为tile[index][0]即可,逻辑完全一致。
修正后核心代码
AnimationController? controller; Animation<double>? animation; @override void initState() { super.initState(); controller = AnimationController(duration: const Duration(seconds: 3), vsync: this) ..addListener(() => setState(() {})); animation = Tween(begin: -500.0, end: 500.0).animate(controller!); controller!.forward(); } // 直接用tile存储每个位置的颜色状态,初始为'black' List<String> tile = List.filled(4, 'black'); @override Widget build(BuildContext context) { return Container( color: Colors.white, child: ListView.builder( reverse: false, itemCount: tile.length, itemBuilder: (BuildContext context, int index) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { // 只修改当前点击下标的状态 if (tile[index] == 'black') { tile[index] = 'transparent'; } else if (tile[index] == 'transparent') { tile[index] = 'red'; } else { tile[index] = 'black'; } }); }, child: Transform.translate( offset: Offset(0.0, animation!.value), child: Container( height: MediaQuery.of(context).size.height / 4, // 直接从tile读取对应下标的颜色 color: switch(tile[index]) { 'black' => Colors.black, 'transparent' => Colors.transparent, 'red' => Colors.red, _ => Colors.green }, child: Text(tile[index], style: const TextStyle(color: Colors.purple)), ), ), ); }, ) ); }
内容的提问来源于stack exchange,提问作者Joshua Jenny Sibbu
相关产品推荐
相关产品推荐

