天天看点

一个TextView显示2中颜色(动态变色)

之前写了一次静态的颜色,这次加上动画效果。

先上效果:

一个TextView显示2中颜色(动态变色)

自定义view:GradientColorDynamicTextView 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;

import androidx.annotation.Nullable;

/**
 * 动态的 改变颜色
 */
public class GradientColorDynamicTextView extends androidx.appcompat.widget.AppCompatTextView {

    // 当前朝向
    private Direction mDirection = Direction.LEFT_TO_RIGHT;
    // 绘制的朝向枚举
    public enum Direction {
        LEFT_TO_RIGHT, RIGHT_TO_LEFT
    }

    //2根画笔
    Paint mOriginalPaint;//原始颜色
    Paint mChangePaint;//改变后的颜色

    public GradientColorDynamicTextView(Context context) {
        this(context,null);
    }

    public GradientColorDynamicTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public GradientColorDynamicTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mOriginalPaint = new Paint();
        mOriginalPaint.setAntiAlias(true);
        mOriginalPaint.setTextSize(getTextSize());

        mChangePaint = new Paint();
        mChangePaint.setAntiAlias(true);
        mChangePaint.setTextSize(getTextSize());
    }

    //默认不绘制
    float mCurrentProgress = 0f;

    @Override
    protected void onDraw(Canvas canvas) {
        //默认是从左到右
        //获取文字的宽带
        String text = getText().toString();
        Rect bound = new Rect();
        mOriginalPaint.getTextBounds(text,0,text.length(),bound);

        //文字的开始位置的x坐标
        int originStartX = (getWidth()-bound.width())/2;

        //左边的宽度,根据progress给左边变色
        int leftWidth=0;
        if(mDirection.equals(Direction.LEFT_TO_RIGHT)){
            mOriginalPaint.setColor(Color.RED);
            mChangePaint.setColor(Color.GRAY);
            //获取左边的宽度
            leftWidth = (int) (getWidth() * mCurrentProgress);
        }else {
            mOriginalPaint.setColor(Color.GRAY);
            mChangePaint.setColor(Color.RED);
            //获取左边的宽度
            leftWidth = (int) (getWidth() * (1-mCurrentProgress));
        }
        //左边
        canvas.save();
        Rect rectLeft = new Rect(0,0,leftWidth,getHeight());
        canvas.clipRect(rectLeft);
        //计算绘制origin的y坐标(baseline) 可复用
        Paint.FontMetrics fontMetrics = mOriginalPaint.getFontMetrics();
        float baseline = (getHeight()-fontMetrics.top-fontMetrics.bottom) / 2;
        //canvas.save后,draw的时候,只会在clip出的区域绘制
        canvas.drawText(text, originStartX, baseline, mOriginalPaint);
        canvas.restore();

        //右边,clip的右边区域
        canvas.save();
        Rect rectRight = new Rect(leftWidth,0,getWidth(),getHeight());
        canvas.clipRect(rectRight);
        //canvas.save后,draw的时候,只会在clip出的区域绘制
        canvas.drawText(text, originStartX, baseline, mChangePaint);
        canvas.restore();
    }

    public void setCurrentProgress(float progress){
        mCurrentProgress = progress;
        invalidate();
    }

    /**
     * 设置方向
     * @param direction
     */
    public void setDirection(Direction direction){
        mDirection = direction;
    }

}
           

布局文件 gradient_tv_color :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    
    <com.test.viewtest.GradientColorDynamicTextView
        android:layout_marginTop="20dp"
        android:id="@+id/gcdt"
        android:padding="04dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="陕西省西安市雁塔区" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="从左到右"
        android:onClick="changeLeftToRight"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="从右到左"
        android:onClick="changeRightToLeft"/>

</LinearLayout>
           

 Activity的使用:GradientColorTextViewActivity

public class GradientColorTextViewActivity extends AppCompatActivity {

    private GradientColorDynamicTextView gcdt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gradient_tv_color);
         gcdt = findViewById(R.id.gcdt);
    }

    public void changeLeftToRight(View view) {
        gcdt.setDirection(GradientColorDynamicTextView.Direction.LEFT_TO_RIGHT);
        @SuppressLint("ObjectAnimatorBinding")
        ObjectAnimator objectAnimator  =  ObjectAnimator.ofFloat(gcdt,"progress",0,1f);
        objectAnimator.setDuration(2000).start();
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float progress = (float) animation.getAnimatedValue();
                gcdt.setCurrentProgress(progress);
            }
        });
    }

    public void changeRightToLeft(View view) {
        gcdt.setDirection(GradientColorDynamicTextView.Direction.RIGHT_TO_LEFT);
        @SuppressLint("ObjectAnimatorBinding")
        ObjectAnimator objectAnimator  =  ObjectAnimator.ofFloat(gcdt,"progress",0,1f);
        objectAnimator.setDuration(2000).start();
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float progress = (float) animation.getAnimatedValue();
                gcdt.setCurrentProgress(progress);
            }
        });
    }
}