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

发布于:2025-08-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

在这里插入图片描述

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

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

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

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



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" />
        <!-- 渐变方向:vertical(默认)、horizontal -->
        <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() 时重新计算。
@Override
protected 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、主题标题,还是特殊提示文字,都可以让界面更具视觉冲击力,同时保持代码的灵活性与可维护性。


网站公告

今日签到

点亮在社区的每一天
去签到