自定义View步骤:
1>:values__attrs.xml,定义自定义属性;
2>:在第三个构造方法中获取自定义属性;
3>:onMeasure【不是必须的】;
4>:onDraw:绘制代码全都在onDraw中写的;
这篇文章主要是结合属性动画自定义一个文字变色的view。先来看效果图。
技术分析:
不能用TextView,因为系统的TextView只能有一种颜色,需要ColorTraceTextView,继承TextView,而不是继承View,原因是:
1>:继承TextView不用自己手动实现onMeasure、onDraw,系统已经实现了;
2>:textColor、textSize属性TextView已经实现了,不用自己实现;
3>: 自定义属性a.不变的颜色 origincolor b.变化的颜色 changcolor
1.字体颜色
自定义属性:attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ColorTrackText">
<attr name="originColor" format="color"/>
<attr name="changeColor" format="color"/>
</declare-styleable>
</resources>
使用属性:avtivity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.view_day04.ColorTrackTextView
android:id="@+id/ColorTrackTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello world"
android:textSize="20sp"
app:changeColor ="@color/purple_200"
app:originColor = "@color/black"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="左到右"
android:onClick="leftToRight"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="右到左"
android:onClick="rightToLeft"/>
</LinearLayout>
2.自定义View–初始化、获取画笔、绘制、实现不同朝向
ColorTrackTextView.java
2.1.初始化、画笔、 绘制
public class ColorTrackTextView extends TextView{
// 绘制不变色的画笔
private Paint mOriginPaint ;
// 绘制变色的画笔
private Paint mChangePaint ;
private float mCurrentProgress = 0.0f;
private Direction mDirection;
//实现不同朝向
public enum Direction {
LEFT_TO_RIGHT,RIGHT_TO_LEFT
}
public ColorTrackTextView(Context context) {
this(context, null);
}
public ColorTrackTextView(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorTrackTextView(Context context, @Nullable @org.jetbrains.annotations.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.ColorTrackText);
// 此处颜色传递默认值,防止你在布局文件中没有指定颜色
int originColor = typedArray.getColor(R.styleable.ColorTrackText_originColor, getTextColors().getDefaultColor());
int changeColor = typedArray.getColor(R.styleable.ColorTrackText_changeColor, getTextColors().getDefaultColor());
mOriginPaint = getPaintByColor(originColor);
mChangePaint = getPaintByColor(changeColor);
typedArray.recycle();
}
private Paint getPaintByColor(int color) {
Paint paint = new Paint() ;
// 给画笔设置颜色
paint.setColor(color);
// 设置抗锯齿
paint.setAntiAlias(true);
// 仿抖动
paint.setDither(true);
// 设置文字大小,拿到布局中的Textsize
paint.setTextSize(getTextSize());
return paint;
}
//利用cliprect可以裁剪,左边用一个画笔去画,右边用另一个画笔去画 不断地改变中间值
@Override
protected void onDraw(Canvas canvas) {
//根据进度把中间值是算出来
int middle = (int)(mCurrentProgress * getWidth());
if (mDirection == Direction.LEFT_TO_RIGHT) {
//绘制不变色的
drawText(canvas,mOriginPaint,0, middle);
//绘制变色的
drawText(canvas,mChangePaint,middle, getWidth());
} else {
// 右-左:
drawText(canvas , mChangePaint , getWidth()-middle , getWidth());
drawText(canvas , mOriginPaint , 0 , getWidth()-middle);
}
}
/**
* 画文字
*/
private void drawText(Canvas canvas, Paint paint, int start, int end) {
// 保存画笔
canvas.save();
Rect rect = new Rect(start,0,end,getHeight()) ;
// 裁剪区域
canvas.clipRect(rect);
// 画文字套路
String text = getText().toString() ;
Rect bounds = new Rect() ;
paint.getTextBounds(text,0,text.length(),bounds);
// 获取字体宽度
int x = getWidth()/2 - bounds.width()/2;
// 基线计算方式
Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom-fontMetricsInt.top)/2-fontMetricsInt.bottom;
int baseLine = getHeight()/2+dy;
canvas.drawText(text,x,baseLine,paint);
// 释放画布
canvas.restore();
}
/**
* 设置朝向
*/
public void setDirection(Direction direction){
this.mDirection = direction;
}
/**
* 设置当前进度
*/
public void setCurrentProgress(float currentProgress){
this.mCurrentProgress = currentProgress;
// 获取到当前进度后,进行重绘
invalidate();
}
/**
* 设置改变的颜色
*/
public void setChangeColor(int color){
this.mChangePaint.setColor(color);
}
}