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

如何让TextButton仅在悬停或聚焦状态下显示底部下划线边框?

解决方案

要实现仅在悬停/聚焦状态下显示底部边框,不需要用shape属性(它会生成全边框),改用ButtonStyle的foregroundDecoration来单独设置底部边框:

修改后的AppTextButtonTheme代码如下:

import 'package:flutter/material.dart';

/// Theme Configuration for light and Dark themes.
class AppTextButtonTheme {
  static final TextButtonThemeData lightTheme = TextButtonThemeData(
    style: ButtonStyle(
      textStyle: MaterialStateProperty.resolveWith<TextStyle?>((Set<MaterialState> states) {
        return AppThemeText.lightTheme.labelLarge;
      }),
      foregroundColor: MaterialStateProperty.resolveWith<Color?>((state) => _getForegroundColor(state, true)),
      overlayColor: MaterialStateProperty.resolveWith<Color?>((state) => _getOverlayColor(state, true)),
      // 替换原来的shape为foregroundDecoration
      foregroundDecoration: MaterialStateProperty.resolveWith<Decoration?>((states) => _getBottomBorder(states, true)),
    ),
  );

  // 深色主题配置
  static final TextButtonThemeData darkTheme = TextButtonThemeData(
    style: ButtonStyle(
      textStyle: MaterialStateProperty.resolveWith<TextStyle?>((Set<MaterialState> states) {
        return AppThemeText.darkTheme.labelLarge;
      }),
      foregroundColor: MaterialStateProperty.resolveWith<Color?>((state) => _getForegroundColor(state, false)),
      overlayColor: MaterialStateProperty.resolveWith<Color?>((state) => _getOverlayColor(state, false)),
      foregroundDecoration: MaterialStateProperty.resolveWith<Decoration?>((states) => _getBottomBorder(states, false)),
    ),
  );

  static Decoration? _getBottomBorder(Set<MaterialState> states, bool isLightMode) {
    if (states.contains(MaterialState.hovered) || states.contains(MaterialState.focused)) {
      return BoxDecoration(
        border: Border(
          bottom: BorderSide(
            width: 3,
            color: isLightMode ? Colors.blue : Colors.red,
          ),
        ),
        // 可选:给底部边框添加圆角,和原有需求匹配
        borderRadius: const BorderRadius.vertical(bottom: Radius.circular(30)),
      );
    }
    return null;
  }

  // 保留原有颜色逻辑方法
  static Color? _getForegroundColor(Set<MaterialState> states, bool isLightMode) {
    // 你的原有实现
  }

  static Color? _getOverlayColor(Set<MaterialState> states, bool isLightMode) {
    // 你的原有实现
  }
}

改动说明

  1. 替换shape为foregroundDecoration:shape的OutlinedBorder会生成完整边框,而foregroundDecoration通过BoxDecoration可以单独指定底部边框,更贴合需求。
  2. 状态控制边框显隐:在_getBottomBorder方法中,仅在悬停/聚焦状态返回带底部边框的装饰,其他状态返回null,实现边框按需显示。
  3. 可选圆角适配:如果需要底部边框带圆角,通过borderRadius.vertical单独设置底部圆角,和原有设计保持一致。

修改后,TextButton会仅在悬停或聚焦时显示底部边框,同时保留Theme全局配置的特性,无需创建自定义组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:20:35