Flutter中点击ListView.builder内Card按钮如何仅更新对应项的数值
问题原因
所有Card共用父组件_MenuCartWidgetState里的同一个count变量,修改这个全局变量自然会触发所有Card的计数同步更新。
解决方案1:抽离独立的Card组件(更推荐)
把每个带计数功能的Card单独封装为StatefulWidget,每个组件自己维护自己的count状态,互不干扰,耦合度更低。
// 独立封装的带计数功能的Card组件 class CountCard extends StatefulWidget { const CountCard({Key? key}) : super(key: key); @override State<CountCard> createState() => _CountCardState(); } class _CountCardState extends State<CountCard> { // 每个Card自己维护count,互不影响 int count = 1; @override Widget build(BuildContext context) { return Card( child: Column( children: [ const Text('test'), Row( children: [ TextButton( onPressed: () { setState(() { count--; }); }, child: const Text('-'), ), Text(count.toString()), TextButton( onPressed: () { setState(() { count++; }); }, child: const Text('+'), ), ], ) ], ), ); } } // 修改后的父组件 class MenuCartWidget extends StatefulWidget { const MenuCartWidget({Key? key}) : super(key: key); @override _MenuCartWidgetState createState() => _MenuCartWidgetState(); } class _MenuCartWidgetState extends State<MenuCartWidget> { @override Widget build(BuildContext context) { var height = MediaQuery.of(context).size.height; var width = MediaQuery.of(context).size.width; return Scaffold( body: Container( child: Padding( padding: const EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0), child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.vertical, itemCount: 5, itemBuilder: (BuildContext context, int index) { return const CountCard(); }), ), ), ); } }
解决方案2:父组件维护计数列表
如果需要在父层统一管理所有卡片的计数值,可以定义一个List类型的状态存储每个下标对应的count值,修改时只修改对应下标的数值即可。
class MenuCartWidget extends StatefulWidget { const MenuCartWidget({Key? key}) : super(key: key); @override _MenuCartWidgetState createState() => _MenuCartWidgetState(); } class _MenuCartWidgetState extends State<MenuCartWidget> { // 初始化长度和列表项数量一致的计数数组,默认值都是1 List<int> countList = List.generate(5, (index) => 1); @override Widget build(BuildContext context) { var height = MediaQuery.of(context).size.height; var width = MediaQuery.of(context).size.width; return Scaffold( body: Container( child: Padding( padding: const EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0), child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.vertical, itemCount: countList.length, itemBuilder: (BuildContext context, int index) { return Card( child: Column( children: [ const Text('test'), Row( children: [ TextButton( onPressed: () { setState(() { // 仅修改当前下标对应的计数 countList[index]--; }); }, child: const Text('-')), // 读取当前下标对应的计数 Text(countList[index].toString()), TextButton( onPressed: () { setState(() { // 仅修改当前下标对应的计数 countList[index]++; }); }, child: const Text('+')), ], ) ], ), ); }), ), ), ); } }
内容的提问来源于stack exchange,提问作者Mohammed Nabil
相关产品推荐
相关产品推荐

