为什么接入SharedPreference后ListView.builder中所有toggle开关同步切换?
问题根源
所有开关共用了同一个SharedPreferences存储key toggleTask,任意一个开关修改该值后,所有开关都会读取同一个全局状态,导致全部同步切换。
解决方案
给每个位置的开关生成独立的唯一存储key,用列表索引i拼接基础key即可,每个开关只读写自己对应的key值。
修改后的核心代码
class _MyScreenState extends State<MyScreen> { var data = Data(); Widget build(BuildContext context) { return Scaffold( body: ListView.builder( itemCount: data.pc.childClass.length, itemBuilder: (context, i) { // 生成当前开关独有的存储key final String toggleKey = "toggleTask_$i"; return Container( child: AnimatedContainer( duration: Duration(milliseconds: 1000), height: 35.0, width: 70.0, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.0), color: this.preferences?.getBool(toggleKey) ?? data.prnt[i].childClass[0].isOn ? Color(0xFF1F8BD0): Colors.grey[100]!.withOpacity(0.2) ), child: Stack( children: <Widget>[ AnimatedPositioned( duration: Duration(milliseconds: 400), curve: Curves.ease, left: this.preferences?.getBool(toggleKey) ?? data.prnt[i].childClass[0].isOn ? 30.0 : 0.0, right: this.preferences?.getBool(toggleKey) ?? data.prnt[i].childClass[0].isOn ? 0.0 : 30.0, child: InkWell( onTap: () { setState(() { data.prnt[i].childClass[0].isOn = ! data.prnt[i].childClass[0].isOn; // 仅修改当前开关对应的存储值 this.preferences?.setBool(toggleKey, data.prnt[i].childClass[0].isOn); }); }, child: AnimatedSwitcher( duration: Duration(milliseconds: 10), transitionBuilder: (Widget child, Animation<double> animation) { return ScaleTransition(child: child, scale: animation); }, child: this.preferences?.getBool(toggleKey) ?? data.prnt[i].childClass[0].isOn ? Icon(Icons.circle, color: Colors.white, size: 35.0, key: UniqueKey(), ) : Icon(Icons.circle, color: Colors.white, size: 35.0, key: UniqueKey(), ), ), ), ), ], ), ) ); } ) ); } }
内容的提问来源于stack exchange,提问作者jobid58525
相关产品推荐
相关产品推荐

