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

如何在FlatButton触发highlightColor时同步修改内部Text文字颜色?

嘿,要实现长按按钮时改变内部文字颜色的需求,我有几个实用的方案,咱们来一步步看:

方案一:使用官方推荐的TextButton(优先选择)

首先提一句:FlatButton在Flutter 2.0之后已经被官方标记为废弃啦,推荐用TextButton这类新按钮组件来替代。它可以通过MaterialStateProperty轻松实现状态联动的样式,完全不需要手动管理状态,非常省心。

修改后的代码如下:

class DefaultButton extends StatelessWidget {
  const DefaultButton({
    Key? key,
    this.text,
    this.press,
    this.buttonColor = primaryColor,
  }) : super(key: key);

  final String? text;
  final VoidCallback? press;
  final Color buttonColor;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 50,
      child: TextButton(
        style: TextButton.styleFrom(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
          backgroundColor: buttonColor,
          // 根据按钮状态动态切换文字颜色
          foregroundColor: MaterialStateProperty.resolveWith<Color>((states) {
            // 当按钮处于长按或按下状态时,切换文字颜色
            if (states.contains(MaterialState.pressed) || states.contains(MaterialState.longPress)) {
              return Colors.white; // 这里替换成你想要的长按状态文字颜色
            }
            return primaryColor; // 默认文字颜色
          }),
          overlayColor: MaterialStateProperty.all(Colors.yellow), // 对应原来的highlightColor
        ),
        onPressed: press,
        child: Text(
          text ?? '',
          style: TextStyle(
            fontFamily: primaryFontFamily,
            fontWeight: FontWeight.w400,
            fontSize: 20,
          ),
        ),
      ),
    );
  }
}

为啥推荐这个方案?

  • 完全遵循官方的组件迭代方向,避免使用废弃组件带来的潜在问题
  • 利用Flutter内置的状态管理逻辑,不需要自己写额外的状态代码,代码更简洁易维护
  • 自动适配所有按钮交互状态(按下、长按、禁用等),扩展性更强
方案二:基于现有FlatButton的修改(兼容旧代码)

如果你暂时不想替换FlatButton,那可以把组件改成StatefulWidget,通过监听长按事件来手动切换文字颜色:

class DefaultButton extends StatefulWidget {
  const DefaultButton({
    Key? key,
    this.text,
    this.press,
    this.buttonColor = primaryColor,
  }) : super(key: key);

  final String? text;
  final VoidCallback? press;
  final Color buttonColor;

  @override
  State<DefaultButton> createState() => _DefaultButtonState();
}

class _DefaultButtonState extends State<DefaultButton> {
  bool _isHighlighted = false;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 50,
      child: GestureDetector(
        // 监听长按开始事件,切换高亮状态
        onLongPressStart: (_) {
          setState(() {
            _isHighlighted = true;
          });
        },
        // 监听长按结束事件,重置高亮状态
        onLongPressEnd: (_) {
          setState(() {
            _isHighlighted = false;
          });
        },
        // 处理点击事件,同时确保状态重置
        onTap: () {
          setState(() {
            _isHighlighted = false;
          });
          widget.press?.call();
        },
        child: FlatButton(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
          highlightColor: Colors.yellow,
          color: widget.buttonColor,
          onPressed: () {}, // 这里留空,避免和GestureDetector的事件冲突
          child: Text(
            widget.text ?? '',
            style: TextStyle(
              fontFamily: primaryFontFamily,
              fontWeight: FontWeight.w400,
              fontSize: 20,
              // 根据高亮状态切换文字颜色
              color: _isHighlighted ? Colors.white : primaryColor,
            ),
          ),
        ),
      ),
    );
  }
}

这个方案的注意点:

  • 需要把原来的StatelessWidget改成StatefulWidget来维护高亮状态
  • 用GestureDetector包裹FlatButton,监听长按的开始和结束事件
  • FlatButton的onPressed要留空,避免和GestureDetector的点击事件产生冲突

内容的提问来源于stack exchange,提问作者Aleksa Vujisic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:02:53