Flutter BMI计算器:修复setState构建错误后onTap点击无响应问题
问题修复:BMI计算器性别卡片点击无响应+setState构建错误
问题根源
- 点击无响应原因:
ReusableCard组件中GestureDetector的onTap绑定错误,使用onPress()会在组件构建时立即执行回调函数,而非点击时触发,导致点击事件未被正确注册。 - 原setState错误原因:组件构建阶段直接执行
onPress()里的setState,触发"setState() or markNeedsBuild() called during build."错误,后续添加的addPostFrameCallback虽规避了错误,但未解决点击绑定的核心问题。
修复步骤
1. 修正ReusableCard组件的回调绑定
将onTap的函数调用改为传递函数引用,并明确回调类型为VoidCallback:
import 'package:flutter/material.dart'; class ReusableCard extends StatelessWidget { final Color colour; final Widget cardChild; final VoidCallback onPress; // 明确为VoidCallback类型 ReusableCard({required this.colour, required this.cardChild, required this.onPress}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onPress, // 直接传递函数引用,不要加括号 child: Container( child: cardChild, margin: EdgeInsets.all(15.0), decoration: BoxDecoration( color: colour, borderRadius: BorderRadius.circular(10.0), ), ), ); } }
2. 移除不必要的addPostFrameCallback
修复回调绑定后,setState只会在点击时执行,不会在构建阶段触发错误,因此可以移除包裹代码:
children: <Widget>[ Expanded( child: ReusableCard( onPress: () { setState(() { selectedGender = Gender.male; }); }, colour: selectedGender == Gender.male ? kActiveCardColour : kInactiveCardColour, cardChild: IconContent( icon: FontAwesomeIcons.mars, label: 'MALE', ), ), ), Expanded( child: ReusableCard( onPress: () { setState(() { selectedGender = Gender.female; }); }, colour: selectedGender == Gender.female ? kActiveCardColour : kInactiveCardColour, cardChild: IconContent( icon: FontAwesomeIcons.venus, label: 'FEMALE', ), ), ), ],
效果验证
修改后,点击性别卡片会正确触发setState切换选中状态,同时不会再出现构建期间调用setState的错误。
内容的提问来源于stack exchange,提问作者Alpesh Jasani
相关产品推荐
相关产品推荐

