Flutter篮球计分应用setState触发后计数器值始终为0问题求助
问题根因
Flutter 中 setState() 只会触发其所属 State 对应的组件树重绘。你在 CardDesign1/2/3 等子得分按钮组件中修改了全局静态计数器的值后,调用的是子组件自身的 setState(),只会刷新按钮组件本身,作为父组件的 InputPage 不会触发重绘,因此顶部展示的计数值会一直停留在初始状态0。
最小改动修复方案
不需要修改原有代码的整体结构,仅需要添加父子组件的点击回调、在父组件触发重绘即可,改动点如下:
1. 修改 InputPage 代码
给各个得分按钮组件传入回调函数,回调中修改全局计数器后调用父组件自身的 setState() 触发重绘:
class InputPage extends StatefulWidget { @override _InputPageState createState() => _InputPageState(); } class _InputPageState extends State<InputPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('basketball counter'), ), body: Column( children: <Widget>[ Expanded( // 新增展示队2的得分 child: Row(children: <Widget>[Expanded(child: HoopDesign()), Text(Counter.counter.toString()), Spacer(), Text(Counter2.counter.toString()), Expanded(child: HoopDesign())] ), ), Expanded( child: Row( children: <Widget>[ Expanded( // 传入队1加1分回调 child: CardDesign1(onTap: (){ setState(() { Counter.counter++; }); }), ), Expanded( // 传入队1加3分回调 child: CardDesign3(onTap: (){ setState(() { Counter.counter +=3; }); }), ), Expanded( // 传入队1加2分回调 child: CardDesign2(onTap: (){ setState(() { Counter.counter +=2; }); }), ), ], )), Expanded( child: Row( children: <Widget>[ Expanded( // 传入队2加1分回调 child: CardDesign6(onTap: (){ setState(() { Counter2.counter++; }); }), ), Expanded( // 传入队2加3分回调 child: CardDesign4(onTap: (){ setState(() { Counter2.counter +=3; }); }), ), Expanded( // 传入队2加2分回调 child: CardDesign5(onTap: (){ setState(() { Counter2.counter +=2; }); }), ), ], ), ), Expanded( child: Row( children: <Widget>[ Expanded( child: HoopDesign(), ), ], ), ), ], ), ); } }
2. 修改各个 CardDesign 组件代码
给组件增加接收回调的参数,移除原有内部的计数器修改和setState逻辑,点击时直接调用传入的回调即可,以CardDesign1为例,其余组件修改逻辑完全一致:
class CardDesign1 extends StatefulWidget { // 新增接收回调参数 final Function onTap; const CardDesign1({super.key, required this.onTap}); @override _CardDesign1State createState() => _CardDesign1State(); } class _CardDesign1State extends State<CardDesign1> { @override Widget build(BuildContext context) { return InkWell( // 点击调用传入的回调 onTap: () => widget.onTap(), child: Container( margin: EdgeInsets.all(15), decoration: BoxDecoration( color: Color(0xFFEF7F4D), borderRadius: BorderRadius.circular(10), ), child: Text( 'Vanaf de 1 punter lijn', textAlign: TextAlign.center, style: TextStyle( fontFamily: 'Bullpen3D', fontSize: 20, ), ), height: 100, width: 100, )); } }
其余CardDesign2/3/4/5/6都按照上述逻辑修改,增加onTap回调参数,把原有onTap里的逻辑替换为调用widget.onTap()即可,同时也修复了原有CardDesign3 3分按钮点击无反应的问题。
3. 原有代码无需修改的部分
原来的全局计数器类Counter、Counter2,以及入口代码、HoopDesign组件都可以完全保留,不需要改动。
修改完成后点击得分按钮就会触发父组件InputPage重绘,顶部展示的计数值就会同步更新。
内容的提问来源于stack exchange,提问作者emieleke
相关产品推荐
相关产品推荐

