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

Flutter按钮点击后禁用3秒并修改颜色的实现问题

解决LabelButton点击后禁用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:35:38