Android自定义View之文本变色

2024-05-12 10:48

本文主要是介绍Android自定义View之文本变色,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 1. 概述
        • 1.1 缘由
        • 1.2 效果图
      • 2. 开撸
        • 2.1 分析
        • 2.2 自定义属性
        • 2.3 编写View
        • 2.4 测试
      • 3. 小结

1. 概述

1.1 缘由

在项目中,经常会遇到文字色值渐变效果,比如在ViewPage中的页面指示器,这种实现起来也比较简单,无非是计算偏移量、使用Paint以及Canvas提供的方法即可。

1.2 效果图

在这里插入图片描述

2. 开撸

2.1 分析

该文本有两种颜色,一种默认颜色,一种为要改变的颜色,因此需要两只画笔,根据偏移量,计算对应起始点、结束点使用相应画笔即可。

2.2 自定义属性

在这里,只简单定义三个属性

<declare-styleable name="ColorTrackTextView"><attr name="originColor" format="color" /><attr name="changeColor" format="color" /><attr name="direction" format="enum"><enum name="left2Right" value="1" /><enum name="right2Left" value="2" /></attr>
</declare-styleable>
2.3 编写View

根据分析,继承 TextView,重写onDraw方法即可。
详细注释见代码。

public class ColorTrackTextView extends TextView {private Paint mOriginPaint;private Paint mChangePaint;private float mProgress = 0.0f;private int mStartX = Integer.MIN_VALUE;private float mBaseLine = Float.MAX_VALUE;private Direction mDirection = Direction.LEFT2RIGHT;public ColorTrackTextView(Context context) {this(context, null);}public ColorTrackTextView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint(context, attrs);}private void initPaint(Context context, AttributeSet attrs) {TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);int originColor = typedArray.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor());int changeColor = typedArray.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor());int index = typedArray.getInt(R.styleable.ColorTrackTextView_direction, -1);if (index >= 1) {setDirection(index);}mOriginPaint = getPaintByColor(originColor);mChangePaint = getPaintByColor(changeColor);typedArray.recycle();}private Paint getPaintByColor(int color) {Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setColor(color);paint.setDither(true);paint.setTextSize(getTextSize());return paint;}@Overrideprotected void onDraw(Canvas canvas) {int middle = (int) (mProgress * getWidth());// 从左到右if (mDirection == Direction.LEFT2RIGHT) {// 绘制变色区域drawText(canvas, mChangePaint, 0, middle);// 绘制不变色区域drawText(canvas, mOriginPaint, middle, getWidth());} else {// 从右到左// 绘制变色区域drawText(canvas, mChangePaint, getWidth() - middle, getWidth());// 绘制不变色区域drawText(canvas, mOriginPaint, 0, getWidth() - middle);}}/*** 绘制文本** @param canvas* @param paint* @param start* @param end*/private void drawText(Canvas canvas, Paint paint, int start, int end) {canvas.save();Rect rect = new Rect(start, 0, end, getHeight());canvas.clipRect(rect);canvas.drawText(getText().toString(), getStartX(paint), getBaseLine(paint), paint);canvas.restore();}/*** 计算文字开始X坐标** @param paint* @return*/private int getStartX(Paint paint) {if (mStartX != Integer.MIN_VALUE) return mStartX;String text = getText().toString();Rect bounds = new Rect();paint.getTextBounds(text, 0, text.length(), bounds);mStartX = (getWidth() - bounds.width()) / 2;return mStartX;}/*** 计算baseLine** @param paint* @return*/private float getBaseLine(Paint paint) {if (mBaseLine != Float.MAX_VALUE) return mBaseLine;Paint.FontMetrics fontMetrics = paint.getFontMetrics();float dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;mBaseLine = getHeight() / 2 + dy;return mBaseLine;}public void setDirection(Direction direction) {this.mDirection = direction;}public synchronized void setProgress(float progress) {if (progress < 0) {throw new IllegalArgumentException("进度不能小于0哦");}this.mProgress = progress;invalidate();}private void setDirection(int index) {if (index == 1) {mDirection = Direction.LEFT2RIGHT;} else if (index == 2) {mDirection = Direction.RIGHT2LEFT;}}public enum Direction {LEFT2RIGHT, RIGHT2LEFT}
}    
2.4 测试

验证下效果吧

测试Activity

class ColorTrackActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_color_track)}fun left2Right(view: View) {cttv_content.setDirection(ColorTrackTextView.Direction.LEFT2RIGHT)val anim = ObjectAnimator.ofFloat(0.0f, 1.0f)anim.duration = 5000anim.addUpdateListener { animation ->val progress = animation.animatedValue as Floatcttv_content.setProgress(progress)}anim.start()}fun right2Left(view: View) {cttv_content.setDirection(ColorTrackTextView.Direction.RIGHT2LEFT)val anim = ObjectAnimator.ofFloat(0.0f, 1.0f)anim.duration = 5000anim.addUpdateListener { animation ->val progress = animation.animatedValue as Floatcttv_content.setProgress(progress)}anim.start()}}

activity_color_track布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><com.happy.android.study.view.ColorTrackTextViewandroid:id="@+id/cttv_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="小洋人最happy"android:textSize="28dp"app:changeColor="@android:color/holo_red_dark"app:direction="right2Left" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="12dp"android:orientation="horizontal"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="left2Right"android:text="从左到右渐变" /><Buttonandroid:id="@+id/right2Left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="right2Left"android:text="从右到左渐变" /></LinearLayout>
</LinearLayout>

3. 小结

实现代码比较简单,主要知识点如下:

  • Canvas.clipRect使用
  • 文本基准线计算
  • 偏移量计算

这篇关于Android自定义View之文本变色的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/982420

相关文章

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l