Flutter实现点击后禁用一天的按钮及日期格式异常解决
问题分析与解决方案
问题根源
- FormatException原因:首次打开App时,SharedPreferences中没有存储
time字段,prefs.getString("time")返回null,调用toString()后得到字符串"null",DateTime.parse("null")无法解析,直接抛出日期格式错误。 - 逻辑混乱:未在页面初始化时判断按钮状态,点击时的日期对比和状态重置逻辑顺序错误,导致按钮状态更新不及时。
修正后的完整代码
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class WithdrawPage extends StatefulWidget { const WithdrawPage({super.key}); @override State<WithdrawPage> createState() => _WithdrawPageState(); } class _WithdrawPageState extends State<WithdrawPage> { bool _isButtonEnabled = true; String _buttonTitle = "提现"; @override void initState() { super.initState(); _checkWithdrawStatus(); } // 初始化时检查今日是否已提现 Future<void> _checkWithdrawStatus() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? lastWithdrawTimeStr = prefs.getString("last_withdraw_time"); if (lastWithdrawTimeStr != null) { DateTime lastWithdrawTime = DateTime.parse(lastWithdrawTimeStr); DateTime today = DateTime.now(); // 对比是否为同一天 bool isSameDay = lastWithdrawTime.year == today.year && lastWithdrawTime.month == today.month && lastWithdrawTime.day == today.day; setState(() { _isButtonEnabled = !isSameDay; _buttonTitle = isSameDay ? "今日已提现" : "提现"; }); } } // 处理提现点击事件 Future<void> _handleWithdraw() async { if (!_isButtonEnabled) return; SharedPreferences prefs = await SharedPreferences.getInstance(); DateTime now = DateTime.now(); // 这里替换成你的实际提现业务逻辑 print("执行提现操作"); // 更新状态并保存到SharedPreferences setState(() { _isButtonEnabled = false; _buttonTitle = "今日已提现"; }); await prefs.setString("last_withdraw_time", now.toIso8601String()); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("提现页面")), body: Center( child: ElevatedButton( onPressed: _isButtonEnabled ? _handleWithdraw : null, child: Text(_buttonTitle), ), ), ); } }
关键修改说明
- 初始化检查状态:在
initState中调用_checkWithdrawStatus,页面加载时就判断今日是否已提现,直接设置按钮状态,避免点击时才判断的滞后问题。 - 安全解析日期:先判断
last_withdraw_time是否存在,不存在则视为未提现;存在时用标准的ISO8601格式解析,避免格式错误。 - 按钮状态绑定:
onPressed直接绑定_isButtonEnabled,禁用时设为null,符合Flutter按钮禁用的标准写法。 - 简化逻辑:去掉多余的
one_tap布尔值,直接通过日期对比判断是否可提现,减少状态变量,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Happiness Jen
相关产品推荐
相关产品推荐

