package com.example.colorText;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View view=findViewById(R.id.id_changeTextColorView);
findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
//对象要有set get方法
ObjectAnimator.ofFloat(view, "progress", 0,1).setDuration(3000).start();
}
});
}
}
package com.example.colorText;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.TextView;
public class myView extends View {
private static final String TAG = "myView";
private float progress = 0;
private String text = "橘子群岛";
private int mWidth;
private int mHeight;
private Rect mbounds;
private int textWidth;
private int textHeight;
private int startX;
private int startY;
private Paint paint;
private Paint oriPain;
private boolean isStart = true;
public myView(Context context) {
this(context, null);
}
public myView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public myView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
oriPain = new Paint(Paint.ANTI_ALIAS_FLAG);
oriPain.setColor(0xffff0000);
oriPain.setDither(true);
paint.setTextSize(sp2px(30));
oriPain.setTextSize(sp2px(30));
paint.setStyle(Style.FILL);
// oriPain.setStyle(Style.STROKE);//空心字
oriPain.setStyle(Style.FILL);
paint.setColor(0xff0000ff);
mbounds = new Rect();
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.ColorTrackView);
progress = ta.getFloat(R.styleable.ColorTrackView_progress, 0);
ta.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {measureText();
int width = getWidthMeasure(widthMeasureSpec);
int height = getHeightMeasure(heightMeasureSpec);
setMeasuredDimension(width, height);
startX = getMeasuredWidth() / 2 - textWidth / 2;
startY = getMeasuredHeight() / 2 + textHeight / 2;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void measureText() {
textWidth = (int) oriPain.measureText(text);
FontMetrics fm = oriPain.getFontMetrics();
textHeight = (int) (fm.descent + fm.ascent);
oriPain.getTextBounds(text, 0, text.length(), mbounds);
}
private int getHeightMeasure(int heights) {
int mode = MeasureSpec.getMode(heights);
int val = MeasureSpec.getSize(heights);
int result = 0;
switch (mode) {
case MeasureSpec.EXACTLY:
result = val;
break;
case MeasureSpec.AT_MOST:
// break;//不要break 就可以 把上面的 result = textWidth; 注掉;
case MeasureSpec.UNSPECIFIED:
result = textHeight + getPaddingTop() + getPaddingBottom();
break;
}
// EXACTLY的值 是精确的 最大也是屏幕大小 AT_MOST warp_content 动态大小 不会超过屏幕
result = mode == MeasureSpec.AT_MOST ? Math.min(result, val) : result;
return result;
}
private int getWidthMeasure(int widths) {
int mode = MeasureSpec.getMode(widths);
int width = MeasureSpec.getSize(widths);
int result = 0;
if (mode == MeasureSpec.EXACTLY) {
// 精确值
result = width;
} else if (mode == MeasureSpec.UNSPECIFIED) {
result = textWidth;
}
if (mode == MeasureSpec.AT_MOST) {
result = textWidth + getPaddingLeft() + getPaddingRight();
}
// EXACTLY的值 是精确的 最大也是屏幕大小 AT_MOST warp_content 动态大小 不会超过屏幕
result = mode == MeasureSpec.AT_MOST ? Math.min(result, width) : result;
// 如果这个模式 就会取到 result = textWidth;不会取到超过 math_content
return result;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int l = (int) (startX + progress * mbounds.width());
canvas.drawColor(0xaa11ff11);
canvasDrawLeft(canvas, l);
}
private void canvasDrawOriginal(Canvas canvas) {
//textHeight是负值,getMeasuredHeight() / 2字体的底部在控件中间,要加上字体的一半
canvas.drawText(text,startX ,getMeasuredHeight() / 2-(textHeight) / 2, oriPain);
// 高度一半 减去字体descent()+ ascent()=字体高度 的一半 让字体一半在上面 一半在下面
}
private void canvasDrawLeft(Canvas canvas, int l) {
canvas.save();
canvasDrawOriginal(canvas);
canvas.clipRect(startX, 0, l, getMeasuredHeight());
canvas.drawText(
text,
startX,
getMeasuredHeight() / 2
- ((oriPain.descent() + oriPain.ascent()) / 2), paint);
canvas.restore();
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
invalidate();// 必须 构造 get set 方法不然 接收不到 外面穿进来的值
}
private int sp2px(float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
dpVal, getResources().getDisplayMetrics());
}
}