Flutter中禁用状态按钮点击仍执行代码问题求助
问题描述
我的Flutter应用中有一个按钮,需求为用户点击后当日无法再次点击,按钮将保持禁用状态至次日恢复可用。我已将用户上次点击的时间存储在Firestore中,但当前存在问题:按钮处于禁用状态时,点击仍会执行verifyAccount()方法。以下是我的代码:
@override void initState() { super.initState(); _checkButtonStatus(); } verifyAccount() async { final response = await http.post( Uri.parse('http://'), headers: { "Content-type": "application/x-www-form-urlencoded", "Accept": "application/json", }, body:{ "accountNo": widget.valueAccountNo, "accountName": widget.valueAccountName, "bankName": widget.valueBankName, }); var data = await json.decode(json.encode(response.body)); if(data == "Error"){ } else{ //Get Your ERROR message's here } } Future<void> _checkButtonStatus() async { User? user = _auth.currentUser; _uid = user!.uid; try { DocumentSnapshot documentSnapshot = await _firestore.collection('Withdrawals').doc(_uid).get(); if (documentSnapshot.exists) { Timestamp lastPressed = documentSnapshot['date']; DateTime lastPressedDate = lastPressed.toDate(); DateTime currentDate = DateTime.now(); Duration difference = currentDate.difference(lastPressedDate); setState(() { _isButtonActive = difference.inHours >= 24; }); } } catch (e) { print("Error checking button status: $e"); } } Future<void> _handleButtonPress() async { try { await _firestore.collection('Withdrawals').doc(_uid).set({ 'date': Timestamp.now(), }); setState(() { _isButtonActive = false; }); } catch (e) { print("Error handling button press: $e"); } } child: ElevatedButton( child: Text(_isButtonActive ? 'Continue':'Disabled'), onPressed: _isButtonActive ? () async { await _handleButtonPress(); verifyAccount(); } : null, ),
按钮禁用时不应执行verifyAccount()方法,请问哪里遗漏或处理不当?
解决方案
1. 时间判断逻辑错误(核心问题)
当前用difference.inHours >=24判断是否允许点击,不符合“当日点击后次日恢复”的需求——比如用户今日23点点击,次日0点本应恢复可用,但按当前逻辑要等满24小时(次日23点)才会解锁。
应改为比较日期部分,忽略具体时间:
// 替换_checkButtonStatus中的判断代码 DateTime lastPressedDate = lastPressed.toDate(); DateTime currentDate = DateTime.now(); // 判断是否跨天 bool isNextDay = currentDate.year != lastPressedDate.year || currentDate.month != lastPressedDate.month || currentDate.day != lastPressedDate.day; setState(() { _isButtonActive = isNextDay; });
2. 未处理首次使用场景
当Firestore中无用户点击记录时,_isButtonActive未被赋值,若初始值为false会导致按钮默认禁用。需补充无文档时的逻辑:
// 在_checkButtonStatus的try块中添加 if (documentSnapshot.exists) { // 上述修改后的跨天判断逻辑 } else { setState(() { _isButtonActive = true; // 首次使用允许点击 }); }
3. 关于“禁用时仍执行verifyAccount”的误解
如果是点击按钮后,按钮变为禁用但verifyAccount仍在执行,这是正常流程:点击时按钮处于可用状态,回调已触发,后续setState仅更新UI为禁用,不会中断已启动的代码。若需严格确保只有按钮可用时才执行方法,可在verifyAccount开头增加状态判断:
verifyAccount() async { if (!_isButtonActive) return; // 状态禁用时直接返回 // 原有HTTP请求逻辑 }
4. 检查初始值
确保_isButtonActive的初始值正确,建议初始化为true,避免页面加载时按钮默认禁用:
bool _isButtonActive = true;
内容的提问来源于stack exchange,提问作者Happiness Jen
相关产品推荐
相关产品推荐

