自定義控制元件之字型變色
阿新 • • 發佈:2019-01-02
@SuppressLint("AppCompatCustomView") public class ColorTrackTextView extends TextView { //繪製不變字型的顏色 private Paint originPaint; //改變後字型顏色 private Paint changePaint; //當前進度 private float currentProgress = 0.0f; private Direction direction = Direction.LEFT_TO_RIGHT; public enum Direction { LEFT_TO_RIGHT, RIGHT_TO_LEFT } public ColorTrackTextView(Context context) { this(context, null); } public ColorTrackTextView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); initPaint(context, attrs); } public ColorTrackTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void initPaint(Context context, AttributeSet attrs) { TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView); int originColor = array.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor()); int changeColor = array.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor()); originPaint = getPaintByColor(originColor); changePaint = getPaintByColor(changeColor); // 回收 array.recycle(); } private Paint getPaintByColor(int color) { Paint paint = new Paint(); // 設定顏色 paint.setColor(color); // 設定抗鋸齒 paint.setAntiAlias(true); // 防抖動 paint.setDither(true); // 設定字型的大小 就是TextView的字型大小 paint.setTextSize(getTextSize()); return paint; } @Override protected void onDraw(Canvas canvas) { int middle = (int) (currentProgress * getWidth()); //從左變到右 if (direction == Direction.LEFT_TO_RIGHT) { //繪製變色 drawText(canvas, changePaint, 0, middle); drawText(canvas, originPaint, middle, getWidth()); } else { //從右變到左 drawText(canvas, changePaint, getWidth() - middle, getWidth()); drawText(canvas, originPaint, 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 bound = new Rect(); paint.getTextBounds(text, 0, text.length(), bound); //獲取字型的寬度 int x = getWidth() / 2 - bound.width() / 2; Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt(); int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom; System.out.println("dy:" + dy); int baseLine = getHeight() / 2 + dy; canvas.drawText(text, x, baseLine, paint); canvas.restore(); } public void setOriginColor(int originPaint) { this.originPaint.setColor(originPaint); } public void setChangeColor(int changePaint) { this.changePaint.setColor(changePaint); } public void setCurrentProgress(float currentProgress) { this.currentProgress = currentProgress; invalidate(); } public void setDirection(Direction direction) { this.direction = direction; } }
main_activity核心程式碼:
<?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="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:orientation="vertical" android:paddingTop="@dimen/activity_vertical_margin" > <com.cmj.textviewcolor.ColorTrackTextView android:id="@+id/color_track_tv" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" app:changeColor="@color/colorAccent" android:text="Hello World!" /> <Button android:layout_width="wrap_content" android:text="左到右" android:onClick="leftToRight" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:text="右到左" android:onClick="rightToLeft" android:layout_height="wrap_content" /> </LinearLayout>
public void leftToRight(View view) { colorTrackTextView.setDirection(ColorTrackTextView.Direction.LEFT_TO_RIGHT); ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 1); valueAnimator.setDuration(2000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float animatedValue = (float) valueAnimator.getAnimatedValue(); colorTrackTextView.setCurrentProgress(animatedValue); } }); valueAnimator.start(); } public void rightToLeft(View view) { colorTrackTextView.setDirection(ColorTrackTextView.Direction.RIGHT_TO_LEFT); ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 1); valueAnimator.setDuration(2000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float animatedValue = (float) valueAnimator.getAnimatedValue(); colorTrackTextView.setCurrentProgress(animatedValue); } }); valueAnimator.start(); }