> 技术文档 > 【Android笔记】Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)

【Android笔记】Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)

【Android笔记】Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)

Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)

在 Android UI 设计中,字体颜色的渐变效果能让界面看起来更加精致与现代。常见的渐变有从左到右、从上到下等方向,但 Android 的 TextView 默认并不支持垂直渐变。

本文将带你从原理到实现,一步步完成一个支持 上到下颜色渐变TextView,并且支持在 XML 中直接配置渐变颜色,无须每次写 Java 代码去设置。

本文最终实现效果:文字颜色可从顶部到底部渐变,颜色、方向均可在 XML 中自定义,支持阴影效果,性能开销低,可直接在项目中复用。


文章目录

  • **Android 自定义 TextView 实现垂直渐变字体颜色(支持 XML 配置)**
    • 1. 渐变字体效果原理
    • 2. 自定义 VerticalGradientTextView(支持 XML 配置)
      • 2.1 添加自定义属性
      • 2.2 编写自定义 TextView 类
    • 3. 在 XML 中使用渐变字体 TextView
    • 4. 优化与扩展
      • 4.1 性能优化
      • 4.2 支持更多渐变类型
      • 4.3 与动画结合
    • 总结

1. 渐变字体效果原理

在 Android 中,要实现渐变文字的关键是使用 Shader(着色器),其中 LinearGradient 是最常用的线性渐变工具。

LinearGradient 的构造函数如下:

LinearGradient( float x0, float y0, // 渐变起点坐标 float x1, float y1, // 渐变终点坐标 int color0, // 起始颜色 int color1, // 结束颜色 Shader.TileMode tile)

当我们把 LinearGradient 设置给 TextViewPaint 时,文字在绘制时就会自动按照渐变色进行渲染。

例如,如果我们想要让文字从红色渐变到蓝色,由上到下,可以这么写:

Shader shader = new LinearGradient( 0, 0, 0, getHeight(), Color.RED, Color.BLUE, Shader.TileMode.CLAMP);paint.setShader(shader);

Shader.TileMode.CLAMP 表示渐变会被拉伸填充到末端,不会重复或镜像。


2. 自定义 VerticalGradientTextView(支持 XML 配置)

为了让渐变文字可以在布局 XML 中直接配置,我们需要自定义一个 TextView,并且支持读取自定义属性(startColorendColorgradientOrientation)。


2.1 添加自定义属性

首先,在 res/values/attrs.xml 中定义渐变颜色相关的属性:

<resources> <declare-styleable name=\"VerticalGradientTextView\">  <attr name=\"startColor\" format=\"color\" />  <attr name=\"endColor\" format=\"color\" />  <attr name=\"gradientOrientation\" format=\"enum\"> <enum name=\"vertical\" value=\"0\" /> <enum name=\"horizontal\" value=\"1\" /> </attr> </declare-styleable></resources>

这样,XML 中就可以像设置 android:textColor 一样设置渐变颜色。


2.2 编写自定义 TextView 类

package com.example.gradienttextview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Shader;import android.util.AttributeSet;import androidx.appcompat.widget.AppCompatTextView;public class VerticalGradientTextView extends AppCompatTextView { private int startColor; private int endColor; private int orientation; // 0: vertical, 1: horizontal public VerticalGradientTextView(Context context) { this(context, null); } public VerticalGradientTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public VerticalGradientTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.VerticalGradientTextView); startColor = ta.getColor(R.styleable.VerticalGradientTextView_startColor, 0xFFFF4081); endColor = ta.getColor(R.styleable.VerticalGradientTextView_endColor, 0xFF3F51B5); orientation = ta.getInt(R.styleable.VerticalGradientTextView_gradientOrientation, 0); ta.recycle(); } @Override protected void onDraw(Canvas canvas) { Paint paint = getPaint(); Shader shader; if (orientation == 0) { // 垂直渐变 shader = new LinearGradient(  0, 0, 0, getHeight(),  startColor,  endColor,  Shader.TileMode.CLAMP ); } else { // 水平渐变 shader = new LinearGradient(  0, 0, getWidth(), 0,  startColor,  endColor,  Shader.TileMode.CLAMP ); } paint.setShader(shader); super.onDraw(canvas); }}

3. 在 XML 中使用渐变字体 TextView

创建布局文件 activity_main.xml,直接使用我们的自定义控件:

<com.example.gradienttextview.VerticalGradientTextView android:layout_width=\"112dp\" android:layout_height=\"40dp\" android:text=\"示例文本\" android:textSize=\"28sp\" android:gravity=\"center\" android:shadowColor=\"#40000000\" android:shadowDx=\"0dp\" android:shadowDy=\"4dp\" android:shadowRadius=\"3.0\" app:startColor=\"#FF4081\" app:endColor=\"#3F51B5\" app:gradientOrientation=\"vertical\"/>

这样,文字就会从粉红色(#FF4081)到蓝色(#3F51B5)垂直渐变,并且保留阴影效果。


4. 优化与扩展

4.1 性能优化

  • onDraw() 中每次都会创建 LinearGradient,对于频繁重绘的场景(如动画)可能会增加开销。可以将 LinearGradient 缓存到成员变量,并在 onSizeChanged() 时重新计算。
@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); updateShader(w, h);}private void updateShader(int w, int h) { if (orientation == 0) { shader = new LinearGradient(0, 0, 0, h, startColor, endColor, Shader.TileMode.CLAMP); } else { shader = new LinearGradient(0, 0, w, 0, startColor, endColor, Shader.TileMode.CLAMP); }}

这样 onDraw() 里只需要 paint.setShader(shader);,无需每次创建对象。


4.2 支持更多渐变类型

  • 多色渐变:LinearGradient 支持传入颜色数组和对应位置数组,可以实现三色或更多颜色渐变。
  • 角度渐变:通过计算不同的起止坐标,可以实现任意角度渐变。

4.3 与动画结合

渐变字体可以和 ValueAnimator 结合,让颜色动态变化,实现炫酷的标题效果。

ValueAnimator animator = ValueAnimator.ofArgb(Color.RED, Color.BLUE);animator.addUpdateListener(animation -> { startColor = (int) animation.getAnimatedValue(); invalidate();});animator.setDuration(2000);animator.setRepeatCount(ValueAnimator.INFINITE);animator.start();

总结

通过以上步骤,我们实现了一个:

  • 支持 XML 配置渐变颜色和方向
  • 保持阴影效果
  • 性能优化可选
  • 可扩展为多色渐变和动画

垂直渐变字体 TextView

无论是用于游戏 UI、主题标题,还是特殊提示文字,都可以让界面更具视觉冲击力,同时保持代码的灵活性与可维护性。