Android文字渐变的实现

Android文字渐变的实现

最近设计师提了一个特殊字体,是从上到下渐变的效果。

正常是这样:

intArrayOf(startColor, endColor), // 只需两个颜色

但是我发现颜色不太对,颜色底部的太浅,顶部太深。优化下应该是这样:

intArrayOf(startColor, startColor, endColor, endColor),

可以这样写:

kotlin 复制代码
class GradientTextView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {

    private var startColor = 0x00FFFF.toInt()
    private var endColor = 0xFFFFFF.toInt()

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) updateGradient()
    }

    private fun updateGradient() {
        if (width == 0 || height == 0) return
        paint.shader = LinearGradient(
            0f, 0F,
            0f, height.toFloat(),
            intArrayOf(startColor, startColor, endColor, endColor),
            null,
            Shader.TileMode.CLAMP
        )
        invalidate()
    }
}

下面是AI逐行解释


这段代码是 Android 自定义 View 中用于创建和更新线性渐变效果的代码。让我逐步解释:

1. onLayout 方法

kotlin 复制代码
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)
    if (changed) updateGradient()
}
  • 作用:当 View 的布局发生变化时被调用
  • 参数
    • changed: 布局是否改变(尺寸或位置变化)
    • left/top/right/bottom: View 相对于父容器的位置坐标
  • 逻辑 :只有在布局真正改变时(changed == true)才更新渐变,避免不必要的重绘

2. updateGradient 方法

kotlin 复制代码
private fun updateGradient() {
    if (width == 0 || height == 0) return  // ①
    paint.shader = LinearGradient(         // ②
        0f, 0f,                            // 起点坐标 (x1, y1)
        0f, height.toFloat(),              // 终点坐标 (x2, y2)
        intArrayOf(startColor, startColor, endColor, endColor),  // ③
        null,                              // ④
        Shader.TileMode.CLAMP              // ⑤
    )
    invalidate()                           // ⑥
}

关键点解析

尺寸检查

  • 避免在 View 还未测量完成时创建渐变(width/height 为 0)

LinearGradient 线性渐变

  • (0, 0)(0, height) 创建垂直渐变(从上到下)

颜色数组

kotlin 复制代码
intArrayOf(startColor, startColor, endColor, endColor)
  • 包含 4 个颜色值,但只有两种颜色
  • 这样配置会创建特殊的渐变效果(可能是为了控制渐变的分布)

位置数组为 null

  • 不指定颜色的位置,系统会均匀分布颜色
  • 如果是 [0f, 0.3f, 0.7f, 1f] 则可以精确控制每个颜色的位置

TileMode.CLAMP

  • 超出渐变范围的区域使用边缘颜色填充

invalidate()

  • 触发 View 重绘,使新的渐变生效

渐变效果示意

复制代码
┌─────────────┐
│ startColor  │ ← 顶部
│ startColor  │
│             │ 
│   渐变过渡   │
│             │
│  endColor   │
│  endColor   │ ← 底部
└─────────────┘

可能的改进建议

如果想要简单的双色渐变,可以简化为:

kotlin 复制代码
paint.shader = LinearGradient(
    0f, 0f,
    0f, height.toFloat(),
    intArrayOf(startColor, endColor),  // 只需两个颜色
    null,
    Shader.TileMode.CLAMP
)
相关推荐
2501_937189235 小时前
莫凡电视:地方台专属聚合 稳定直播播放工具
android·源码·源代码管理
耶叶6 小时前
Android 新权限申请模型(Activity Result API)
android
阿拉斯攀登6 小时前
【RK3576 安卓 JNI/NDK 系列 04】JNI 核心语法(下):字符串、数组与对象操作
android·驱动开发·rk3568·瑞芯微·rk安卓驱动·jni字符串操作
2501_915909066 小时前
不用越狱就看不到 iOS App 内部文件?使用 Keymob 查看和导出应用数据目录
android·ios·小程序·https·uni-app·iphone·webview
llxxyy卢6 小时前
web部分中等题目
android·前端
轩情吖6 小时前
MySQL之事务管理
android·后端·mysql·adb·事务·隔离性·原子性
万物得其道者成7 小时前
uni-app Android 离线打包:多环境(prod/dev)配置
android·opencv·uni-app
符哥20087 小时前
Firebase 官方提供的Quick Start-Android 库的功能集讲解
android
koeda7 小时前
android17系统兼容
android·安卓
进击的cc8 小时前
面试官:Handler 没消息时为啥不卡死?带你从源码到底层内核彻底整明白!
android·面试