1. 程式人生 > >仿今日頭條的滾動指示器的效果

仿今日頭條的滾動指示器的效果

public class ColorChangeTextView extends TextView {

    private int mPreviousColor = Color.BLUE;
    private int mChangeColor = Color.RED;

    private Paint mPreviousPaint;
    private Paint mChangePaint;
    private Rect bounds = new Rect();

    private float currentOffset = 0.0f;

    //當前顏色變化的方向
    private Direction mDirection = Direction.LEFT_TO_RIGHT;

    //表示顏色變化的方向
    public enum Direction{
        LEFT_TO_RIGHT,RIGHT_TO_LEFT;
    }

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

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

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

        //獲取自定義屬性
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.ColorChangeTextView);

        mPreviousColor = typedArray.getColor(R.styleable.ColorChangeTextView_previousColor,getTextColors().getDefaultColor());
        mChangeColor = typedArray.getColor(R.styleable.ColorChangeTextView_changeColor,getTextColors().getDefaultColor());

        //回收
        typedArray.recycle();

        //設定畫筆
        mPreviousPaint = getColorPaint(mPreviousColor);
        mChangePaint = getColorPaint(mChangeColor);

        bounds = new Rect();
    }

    private Paint getColorPaint(int color){
        Paint paint = new Paint();
        paint.setColor(color);
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setTextSize(60);
        return paint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //自己來畫,呼叫TextView的畫的方法,就會把文字都畫上同一種顏色
        //super.onDraw(canvas);

        if(mDirection == Direction.LEFT_TO_RIGHT){
            drawText(canvas,mChangePaint,0,(int) (getWidth()*currentOffset));
            drawText(canvas,mPreviousPaint,(int) (getWidth()*currentOffset),getWidth());
        }else{
            drawText(canvas,mChangePaint,(int) (getWidth()*(1-currentOffset)),getWidth());
            drawText(canvas,mPreviousPaint,0,(int) (getWidth()*(1-currentOffset)));
        }
    }

    private void drawText(Canvas canvas,Paint paint,int start,int end){

        canvas.save();

        String text = getText().toString();
        //預設畫在中心位置上
        paint.getTextBounds(text,0,text.length(),bounds);

        //計算基線
        Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
        int dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;
        int baseLine = getHeight()/2 + dy;

        Rect rect = new Rect(start,0, end,getHeight());
        canvas.clipRect(rect);
        canvas.drawText(text,getWidth()/2-bounds.width()/2,baseLine,paint);
        
        //記得在裁剪操作之後,還原到之前的狀態  這樣  才能繼續使用
        canvas.restore();
    }

    //設定當前顏色變化的百分比
    public void setCurrentOffset(float currentOffset) {
        this.currentOffset = currentOffset;
        invalidate();
    }

    //設定當前顏色變化的方向
    public void setDirection(Direction direction) {
        mDirection = direction;
    }

    //設定變化的顏色
    public void setChangeColor(int changeColor) {
        this.mChangePaint.setColor(changeColor);
    }

    //設定沒變的顏色
    public void setPreviourColor(int previourColor) {
        this.mPreviousPaint.setColor(previourColor);
    }
}
程式碼中,使用了一個canvas.clipRect()的函式,該函式是截取了畫布的一塊區域,來顯示對應的該區域的操作!