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

Flutter Hero动画跳转详情页时文本短暂出现黄色下划线问题求助

Hero动画过渡时详情页文本短暂出现黄色下划线

问题描述

我开发了一个包含ListView.builder的HomeScreen,点击列表项会通过Hero Animation跳转到对应详情页,但打开详情页时,文本下方会短暂出现黄色下划线,随后消失。

相关代码

return SafeArea(
  child: Scaffold(
    body: LayoutBuilder(
      builder: (p0, constraints) => Hero(
        tag: productLink,
        child: Stack(
          children: [
            Column(
              children: [
                //Main image, title, backButton
                Flexible(
                  child: Stack(
                    alignment: Alignment.bottomRight,
                    children: [
                      AspectRatio(
                        aspectRatio: 16 / 9,
                        child: Image.asset(
                          'assets/dummy/dummy-2.jpg',
                          width: double.infinity,
                          fit: BoxFit.cover,
                        ),
                      ),
                      Align(
                        alignment: Alignment.bottomRight,
                        heightFactor: 1,
                        child: Padding(
                          padding: EdgeInsets.symmetric(
                            horizontal: constraints.maxWidth * .05,
                            vertical: constraints.maxWidth * .02,
                          ),
                          child: Icon(
                            Icons.crop_free_sharp,
                            color: Colors.white.withOpacity(.7),
                            size: Sizes.SIZE_36,
                          ),
                        ),
                      ),
                      //Title
                      Align(
                        alignment: Alignment.bottomLeft,
                        heightFactor: 1,
                        child: Padding(
                          padding: EdgeInsets.symmetric(
                            horizontal: constraints.maxWidth * .03,
                            vertical: constraints.maxWidth * .04,
                          ),
                          child: Text(
                            'Just an empty Adress',
                            style: TextStyle(
                              color: Colors.white.withOpacity(.7),
                              fontSize: Sizes.TEXT_SIZE_20,
                              fontFamily: 'Intel',
                            ),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
                Flexible(
                  child: SizedBox(
                    height: 100,
                    width: double.infinity,
                    child: Stack(
                      children: [
                        Row(
                          children: [
                            Flexible(
                              child: Image.asset(
                                'assets/dummy/dummy-3.jpg',
                                height: 100,
                                width: constraints.maxWidth / 3,
                                fit: BoxFit.cover,
                                cacheWidth: 1440,
                                cacheHeight: 810,
                              ),
                            ),
                            Flexible(
                              child: Image.asset(
                                'assets/dummy/dummy-4.jpg',
                                height: 100,
                                width: constraints.maxWidth / 3,
                                fit: BoxFit.cover,
                              ),
                            ),
                            Flexible(
                              child: Image.asset(
                                'assets/dummy/dummy-5.jpg',
                                height: 100,
                                width: constraints.maxWidth / 3,
                                fit: BoxFit.cover,
                              ),
                            ),
                          ],
                        ),
                        GestureDetector(
                          child: Container(
                            color: Colors.black.withOpacity(0.6),
                            height: 100,
                            width: constraints.maxWidth / 3,
                            child: const Center(
                                child: Text(
                              '+16',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: Sizes.TEXT_SIZE_20,
                                fontWeight: FontWeight.bold,
                              ),
                            )),
                          ),
                        )
                      ],
                    ),
                  ),
                ),
              ],
            ),
            // BackButton
            GestureDetector(
              onTap: () => Navigator.pop(context),
              child: Padding(
                padding: EdgeInsets.symmetric(
                  horizontal: constraints.maxWidth * .05,
                  vertical: constraints.maxWidth * .02,
                ),
                child: CircleAvatar(
                  backgroundColor: Colors.grey.withOpacity(.5),
                  child: const Icon(
                    CupertinoIcons.back,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  ),
);

解决方案

1. 显式关闭文本装饰

这种黄色下划线通常是动画过渡过程中Text组件的临时渲染样式异常导致的,给所有出现问题的Text组件显式添加decoration: TextDecoration.none,强制禁用下划线:

修改标题文本:

Text(
  'Just an empty Adress',
  style: TextStyle(
    color: Colors.white.withOpacity(.7),
    fontSize: Sizes.TEXT_SIZE_20,
    fontFamily: 'Intel',
    decoration: TextDecoration.none, // 新增该行
  ),
)

修改+16文本:

Text(
  '+16',
  style: TextStyle(
    color: Colors.white,
    fontSize: Sizes.TEXT_SIZE_20,
    fontWeight: FontWeight.bold,
    decoration: TextDecoration.none, // 新增该行
  ),
)

2. 缩小Hero组件的范围

当前代码将整个详情页的Stack都包裹在Hero中,范围过大可能导致动画过程中元素渲染冲突。建议只将需要过渡的核心元素(比如主图片)包裹在Hero里,而非整个页面内容:

示例修改:

// 将Hero从LayoutBuilder的子位置移到主Image外层
AspectRatio(
  aspectRatio: 16 / 9,
  child: Hero(
    tag: productLink,
    child: Image.asset(
      'assets/dummy/dummy-2.jpg',
      width: double.infinity,
      fit: BoxFit.cover,
    ),
  ),
),

这样既保留Hero动画效果,又避免了整个页面元素参与动画引发的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:15:26