前言
文本渐变是一种常见的视觉增强手段,广泛应用于品牌标题、活动文案、价格展示等场景,可以说,文字的渐变,让平平无奇的页面变得具有吸引力,具有科技高级感。

那么如何实现这样的一个文字渐变效果呢?目前官方给出了两种实现方式:
1、API 20 及以上:直接使用Text组件的shaderStyle属性设置字体渐变,这是官方推荐的标准方案。
2、API 20 之前:结合blendMode混合模式与linearGradient,通过离屏渲染裁切出文字形状的渐变区域。
shaderStyle属性实现
如果系统的Api版本在20及以上,官方主推shaderStyle属性来实现文字的渐变效果,因为实现起来特别的简单,它是Text组件新增的属性,可以直接将渐变效果作用于文字本身,该属性接受ShaderStyle类型参数,其中LinearGradientStyle 用于线性渐变,RadialGradientStyle 用于径向渐变。
这种方式的优势在于:无需额外的容器包裹,无需混合模式裁切,代码结构简洁,渲染性能更优。
// 定义渐变参数:从左到右,蓝色到青色const BRAND_GRADIENT: LinearGradientOptions = { direction: GradientDirection.Right, colors: [ ['#FF0253EB', 0.0], // 起始颜色:不透明蓝色 ['#FF26ECFF', 1.0] // 结束颜色:不透明青色 ]}@Entry@Component struct TextGradientBasicPage { build() { Column({ space: 24 }) {// 使用 shaderStyle 直接设置文字渐变 Text('HarmonyOS') .fontSize(42) .fontWeight(FontWeight.Bold) .shaderStyle(new LinearGradientStyle(BRAND_GRADIENT))// 斜向渐变示例 Text('限时优惠') .fontSize(32) .fontWeight(FontWeight.Medium) .shaderStyle(new LinearGradientStyle({ angle: 45, colors: [ ['#FFFF4D4F', 0.0], // 红色起始 ['#FFFFA940', 1.0] // 橙色结束 ] })) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }效果如下:

多色渐变示例
colors数组支持配置多个颜色断点,实现更丰富的渐变过渡:
// 多色渐变参数:科技蓝 → 清新青 → 草绿色 → 暖橙色const MULTI_COLOR_GRADIENT: LinearGradientOptions = { direction: GradientDirection.Right, colors: [ ['#FF0253EB', 0.0], ['#FF26ECFF', 0.33], ['#FF00C853', 0.66], ['#FFFFA940', 1.0] ]}@Entry@Component struct MultiColorGradientPage { build() { Column({ space: 20 }) { Text('多色渐变标题') .fontSize(36) .fontWeight(FontWeight.Bold) .shaderStyle(new LinearGradientStyle(MULTI_COLOR_GRADIENT)) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }效果如下:

blendMode + linearGradient实现
shaderStyle属性是API20及以上的版本才会出现,如果要适配低于20的系统,只能通过blendMode + linearGradient来实现了。
其实现原理是:
1、内层Text设置blendMode(BlendMode.DST_IN, BlendApplyType.OFFSCREEN),将文字作为遮罩,保留文字区域,裁剪超出部分。
2、外层容器设置linearGradient渐变背景,提供颜色来源。
3、外层再设置 blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN),将渐变色叠加到文字遮罩上方。
4、BlendApplyType.OFFSCREEN确保离屏渲染,避免混合模式干扰最终效果。
@Entry@Componentstruct TextGradientBlendModePage {@State message: string = 'Hello World' build() { RelativeContainer() { Row() { Text(this.message) .fontSize(24) .fontWeight(FontWeight.Bold)// 内层:将文字作为目标遮罩,裁剪非文字区域 .blendMode(BlendMode.DST_IN, BlendApplyType.OFFSCREEN) }// 外层:设置渐变背景作为颜色来源 .linearGradient({ direction: GradientDirection.Right, colors: [ ['#ff0631f5', 0.0], // 蓝色起始 ['#ff922626', 1.0] // 红色结束 ] })// 外层:将渐变色叠加到文字遮罩上方 .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN) .alignRules({ center: { anchor: "__container__", align: VerticalAlign.Center }, middle: { anchor: "__container__", align: HorizontalAlign.Center } }) } .width('100%') .height('100%') }}
这种方案虽然能实现效果,但存在以下局限:需要额外的容器嵌套,离屏渲染带来一定的性能开销,且代码结构相对复杂。因此在 API 20 及以上版本中,推荐优先使用shaderStyle方案。
LinearGradientOptions对象包含以下核心参数:
direction和 angle 用于控制渐变方向,两者互斥,设置 angle 后 direction 不生效。
GradientDirection 枚举值包括:

angle参数接受 number或 string 类型。以数字传入时单位为度,0 点方向顺时针旋转为正向角度,默认值为 180。以字符串传入时需携带单位,支持 'deg'、'grad'、'rad'、'turn' 四种单位。
colors是渐变的核心参数,类型为 Array<[ResourceColor, number]>。每个元素是一个二元组:第一个值为颜色,第二个值为位置,取值范围 [0, 1.0],0 表示渐变起始处,1.0 表示渐变结束处。
颜色值支持多种格式:
多个颜色断点的位置参数建议递增设置。若后一个断点的位置小于前一个,系统会按等于前一个的位置值处理。
repeating是布尔类型参数,默认值为 false。设为 true 时,会在组件内重复渐变效果7。例如,当颜色断点仅覆盖 0 到 0.3 区域时,设为 true 会在 0.3 到 1.0 区域内重复 0 到 0.3 的渐变效果。
实战案例
下面通过一个完整的示例页面,展示多种文本渐变效果的实际应用:
// 定义渐变配置数据模型interface GradientConfig { name: string options: LinearGradientOptions}// 品牌主色渐变:从左到右,蓝色到青色const BRAND_GRADIENT: LinearGradientOptions = { direction: GradientDirection.Right, colors: [ ['#FF0253EB', 0.0], ['#FF26ECFF', 1.0] ]}// 活动渐变:45度斜向,红色到橙色const PROMO_GRADIENT: LinearGradientOptions = { angle: 45, colors: [ ['#FFFF4D4F', 0.0], ['#FFFFA940', 1.0] ]}// 多色渐变:从左到右,四色过渡const MULTI_GRADIENT: LinearGradientOptions = { direction: GradientDirection.Right, colors: [ ['#FF667eea', 0.0], ['#FF764ba2', 0.33], ['#FFf093fb', 0.66], ['#FFf5576c', 1.0] ]}// 对角渐变:从左上到右下,绿色系const DIAGONAL_GRADIENT: LinearGradientOptions = { direction: GradientDirection.RightBottom, colors: [ ['#FF43e97b', 0.0], ['#FF38f9d7', 1.0] ]}@Entry@Component struct TextGradientShowcasePage {// 渐变配置列表private gradientList: GradientConfig[] = [ { name: '品牌主色', options: BRAND_GRADIENT }, { name: '活动促销', options: PROMO_GRADIENT }, { name: '多色渐变', options: MULTI_GRADIENT }, { name: '对角渐变', options: DIAGONAL_GRADIENT } ] build() { Column({ space: 30 }) {// 页面标题 Text('文本渐变效果展示') .fontSize(28) .fontWeight(FontWeight.Bold) .fontColor('#333333') .margin({ top: 40 })// 遍历展示各种渐变效果 ForEach(this.gradientList, (item: GradientConfig) => { Column({ space: 8 }) { Text(item.name) .fontSize(14) .fontColor('#999999')// 应用渐变效果的文本 Text('HarmonyOS') .fontSize(40) .fontWeight(FontWeight.Bold) .shaderStyle(new LinearGradientStyle(item.options)) } .width('90%') .padding(20) .borderRadius(16) .backgroundColor('#F5F5F5') .alignItems(HorizontalAlign.Center) }, (item: GradientConfig) => item.name) } .width('100%') .height('100%') .alignItems(HorizontalAlign.Center) } }效果如下:

除了线性渐变,shaderStyle还支持径向渐变(RadialGradientStyle),适合实现光感、聚焦和高亮表达:
@Entry@Component struct RadialGradientTextPage { build() { Column({ space: 24 }) { Text('径向渐变文字') .fontSize(40) .fontWeight(FontWeight.Bold) .shaderStyle(new RadialGradientStyle({ center: [50, 20], // 渐变中心点坐标 radius: 60, // 渐变半径 colors: [ ['#FFFFD700', 0.0], // 中心:金色 ['#FFFF4500', 1.0] // 边缘:橙红色 ] })) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }效果如下:

结合 animateTo 动画,可以实现渐变颜色的动态变化效果,例如滚动变色文字:
@Entry@Component struct AnimatedGradientTextPage {@State gradientOffset: number = 0.0 build() { Column({ space: 30 }) {// 动态渐变文字 Text('动态渐变效果') .fontSize(42) .fontWeight(FontWeight.Bold) .shaderStyle(new LinearGradientStyle({ direction: GradientDirection.Right, colors: [ ['#FFFF0000', this.gradientOffset], ['#FF0000FF', this.gradientOffset + 0.5 > 1.0 ? 1.0 : this.gradientOffset + 0.5] ] }))// 触发动画按钮 Button('播放渐变动画') .width('60%') .height(48) .fontSize(16) .onClick(() => {// 使用 animateTo 驱动渐变偏移量变化 animateTo({ duration: 2000, iterations: 1, curve: Curve.Linear }, () => {this.gradientOffset = this.gradientOffset === 0.0 ? 0.5 : 0.0 }) }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }效果如下:

最佳实践与注意事项

使用十六进制数字格式时,格式为 0xAARRGGBB,其中 AA 为透明度通道。0x00 表示完全透明,0xFF 表示完全不透明。常见的错误是将 0x00开头的颜色用于渐变起始,导致透明度未生效。
如果项目需要同时兼容 API 20 之前和之后的版本,可以通过条件判断选择实现方案。但更推荐的做法是统一使用 shaderStyle并将项目的 compileSdkVersion 设置为 API 20 及以上,以获得更简洁的代码和更优的性能。
相关总结
一句话总结,如果系统的Api版本在20及以上,直接使用shaderStyle属性来实现,如果相兼容20以下,那就结合blendMode混合模式与linearGradient,通过离屏渲染裁切出文字形状的渐变区域。