Flutter按钮点击后禁用3秒并修改颜色的实现问题
你的代码核心问题有三个:setState回调不能用异步函数、没有根据状态禁用点击、异步状态更新没正确触发UI刷新。直接改代码如下:
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../utils/definitions.dart'; import 'icons.dart'; import '../model/label.dart'; class LabelButton extends StatefulWidget { final Label? label; final VoidStringCallback? process; LabelButton({required this.label, required this.process, Key? key}) : super(key: key); @override State<LabelButton> createState() => _LabelButtonState(); const LabelButton._(this.label, this.process, {Key? key}) : super(key: key); static LabelButton createBlank() { return const LabelButton._(null, null); } } class _LabelButtonState extends State<LabelButton> { bool _hasBeenPressed = false; // 单独处理点击逻辑 void _handleTap() async { // 先设置为已点击状态,触发UI变色 setState(() { _hasBeenPressed = true; }); // 执行你的业务逻辑和震动 widget.process!(widget.label!.identifier, widget.label!.category, widget.label!.id); HapticFeedback.lightImpact(); // 等待3秒后恢复状态 await Future.delayed(const Duration(seconds: 3)); setState(() { _hasBeenPressed = false; }); } @override Widget build(BuildContext context) { if (widget.label != null) { return Padding( padding: const EdgeInsets.all(8.0), child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Material( child: InkWell( highlightColor: const Color(0xFF00D3F8).withOpacity(0.3), splashColor: const Color(0xFFB20DD3).withOpacity(0.3), // 当_hasBeenPressed为true时,onTap设为null,禁用点击 onTap: _hasBeenPressed ? null : _handleTap, child: Ink( width: 100, height: 120, decoration: BoxDecoration( color: _hasBeenPressed ? const Color(0xFFB6B6B6) : Colors.green, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon( iconList .firstWhere((element) => element.name == widget.label!.uiIcon) .icon, size: 80, ), Text( widget.label!.categoryName, style: const TextStyle( color: Color(0xFF696969), ), ), Text( widget.label!.name, style: const TextStyle( fontWeight: FontWeight.bold, ), ), ], ), ), ), ), ), ); } else { return Container(); } } }
关键修改点:
- 把点击逻辑抽成单独的
_handleTap异步函数,不再把async塞到setState回调里 onTap判断_hasBeenPressed状态,为true时设为null,彻底禁用点击- 状态变更(不管是设为true还是false)都单独用setState包裹,确保UI及时刷新
- 业务逻辑和震动放在状态变更之后,避免重复执行
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

