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

Flutter中如何实现文本垂直方向双色分割显示效果

实现方案

直接用TextStyle的foreground参数绑定渐变着色器即可实现和示例CSS完全一致的效果,比ShaderMask方案更稳定,不会出现渲染错位、颜色覆盖问题。
核心逻辑和CSS的实现完全对应:

  • 线性渐变方向设为顶部到底部
  • 渐变停点卡在50%位置做硬分界,上半部分用深蓝色、下半部分用红色
  • 着色器范围直接绑定文字实际渲染尺寸,不用手动写死宽高

完整可运行示例:

import 'package:flutter/material.dart';

class SplitColorTextPage extends StatelessWidget {
  const SplitColorTextPage({super.key});

  @override
  Widget build(BuildContext context) {
    const targetText = "测试文字内容";
    const baseStyle = TextStyle(fontSize: 40, fontFamily: 'Arial');

    // 提前计算文字实际渲染尺寸,给着色器提供准确范围
    final textSize = (TextPainter(
      text: const TextSpan(text: targetText, style: baseStyle),
      textDirection: TextDirection.ltr,
      maxLines: 1,
    )..layout()).size;

    return Scaffold(
      body: Center(
        child: Text(
          targetText,
          style: baseStyle.copyWith(
            foreground: Paint()
              ..shader = const LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [
                  Color(0xFF0D2172),
                  Color(0xFF0D2172),
                  Color(0xFFFF2828),
                  Color(0xFFFF0000),
                ],
                stops: [0, 0.5, 0.5, 1],
                tileMode: TileMode.clamp,
              ).createShader(Offset.zero & textSize),
          ),
        ),
      ),
    );
  }
}

之前ShaderMask方案失效的常见原因

如果坚持用ShaderMask实现,必须避开几个坑,否则效果必然不对:

  • 必须把blendMode设为BlendMode.srcIn,不然渐变不会裁剪到文字轮廓内部
  • Text组件不能设置任何color属性,不透明的文字色会直接覆盖着色器效果
  • 不要给ShaderMask加多余的padding、父容器不要占满整屏,否则渐变范围会按父组件尺寸计算,分界位置就会错位

ShaderMask的正确写法参考:

ShaderMask(
  shaderCallback: (bounds) => const LinearGradient(
    begin: Alignment.topCenter,
    end: Alignment.bottomCenter,
    colors: [
      Color(0xFF0D2172),
      Color(0xFF0D2172),
      Color(0xFFFF2828),
      Color(0xFFFF0000),
    ],
    stops: [0, 0.5, 0.5, 1],
  ).createShader(bounds),
  blendMode: BlendMode.srcIn,
  child: const Text(
    "测试文字",
    style: TextStyle(fontSize: 40, fontFamily: 'Arial'),
  ),
)

多行文字场景下,两种方案默认都会按整个文本块的总高度计算50%分界,如果需要每一行单独做上下分色,把每行文字拆成独立组件渲染即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:12:27