本文主要是介绍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之文本变色的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!