You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:25:59