1. 程式人生 > >自定義控制元件之字型變色

自定義控制元件之字型變色

@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();
}