Android 自定義控制元件一 帶圓形進度的按鈕 ControlButton2

cswhale發表於2018-01-15

效果圖

這裡寫圖片描述

圖片展示的是中間的圖案ImageView和下面一層自定義控制元件的效果
每次點選都會有一個圓形滾動進度條出現
開始背景黑色,點選後進度條開始滾動,100%時背景變藍持續一定時間後回覆初始

程式碼實現

package com.demo.ui.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.os.Handler;
import android.os.Message;
import android.view.View;


public class ControlButton2 extends View{
    private static final String TAG = "CircleProgressBar";

    private int mMaxProgress = 3000;

    private int mProgress = 0;

    private final int mCircleLineStrokeWidth = 4;

    private final int mTxtStrokeWidth = 2;

    // 畫圓所在的距形區域
    private final RectF mRectF;

    private final Paint mPaint;
    private final Paint mPaintCircle;

    private final Context mContext;

    private String mTxtHint1;

    private String mTxtHint2;
    private SweepGradient mSweepGradient;

    private CBOnTriggerListener cbOnTriggerListener;

    private boolean hasTrigle =false;

    public  boolean isControlButtonRun = false;

    public int circleBackColor = 0xe518151E;//0xFF006CFF

    public int cicleColor = 0xFF0586FB;

    private Runnable runnable;
    private Runnable Stoprunnable;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    public ControlButton2(Context context) {
        super(context);

        mContext = context;
        mRectF = new RectF();
        mPaint = new Paint();
        mPaintCircle = new Paint();

        runnable = new Runnable()
        {
            public void run()
            {
                //sendContinueMessage();
                mProgress += 20;
                setProgress(mProgress);
                handler.postDelayed(this, 20);
                if(mProgress == 3000){
                    stop(controlSuccess);
                }
            }
        };

        Stoprunnable = new Runnable()
        {
            public void run()
            {
                mProgress += 160;
                setProgress(mProgress);
                handler.postDelayed(this, 10);
                if(mProgress >= 3000){
                    hasTrigle = true;
                    stop(controlSuccess);
                }
            }
        };
    }

    @SuppressLint("DrawAllocation") @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = this.getWidth();
        int height = this.getHeight();

        //canvas.drawColor(0xFFFFFF00);
        mSweepGradient = new SweepGradient(width/2, height/2, new int[] {cicleColor,cicleColor,cicleColor,cicleColor,cicleColor}, null);
        if (width != height) {
            int min = Math.min(width, height);
            width = min;
            height = min;
        }

        // 設定畫筆相關屬性
        mPaint.setAntiAlias(true);

        mPaint.setColor(Color.rgb(0xe9, 0xe9, 0xe9));
        canvas.drawColor(Color.TRANSPARENT);
        mPaint.setStrokeWidth(mCircleLineStrokeWidth);
        mPaint.setStyle(Style.STROKE);
        // 位置
        mRectF.left = mCircleLineStrokeWidth / 2; // 左上角x
        mRectF.top = mCircleLineStrokeWidth / 2; // 左上角y
        mRectF.right = width - mCircleLineStrokeWidth / 2; // 左下角x
        mRectF.bottom = height - mCircleLineStrokeWidth / 2; // 右下角y

        // 繪製圓圈,進度條背景
        //canvas.drawArc(mRectF, -90, 360, false, mPaint);
        //mPaint.setColor(Color.rgb(0xf8, 0x60, 0x30));
        canvas.rotate(0, width / 2, height / 2);
        mPaint.setShader(mSweepGradient);
        canvas.drawArc(mRectF,-90, ((float) mProgress / mMaxProgress) * 360, false, mPaint);

        mPaintCircle.setColor(circleBackColor);
        mPaintCircle.setAntiAlias(true);
        mPaintCircle.setStyle(Style.FILL);
        canvas.drawCircle( width / 2, height / 2,(width / 2)-mCircleLineStrokeWidth,mPaintCircle);

    }

    public int getMaxProgress() {
        return mMaxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.mMaxProgress = maxProgress;
    }

    public void setProgress(int progress) {
        this.mProgress = progress;
        this.invalidate();
    }
    public int getmProgress() {
        return mProgress;
    }

    public void setProgressNotInUiThread(int progress) {
        this.mProgress = progress;
        this.postInvalidate();
    }

    public String getmTxtHint1() {
        return mTxtHint1;
    }

    public void setmTxtHint1(String mTxtHint1) {
        this.mTxtHint1 = mTxtHint1;
    }

    public String getmTxtHint2() {
        return mTxtHint2;
    }

    public void setmTxtHint2(String mTxtHint2) {
        this.mTxtHint2 = mTxtHint2;
    }

    public void setCBOnTriggerListener(CBOnTriggerListener listener) {
        cbOnTriggerListener = listener;
    }

    public interface CBOnTriggerListener {
        void trigger();
    }

    public void  start(){
        cicleColor = 0xFF0586FB;
        if(!isControlButtonRun){
            isControlButtonRun = true;
            handler.postDelayed(runnable,0);
        }


    }

    boolean controlSuccess = true;
     int controlTimeDelay = 3000;
    public void stop(boolean controlSuccess)
    {
        this.controlSuccess = controlSuccess;

        handler.removeCallbacks(runnable);
        handler.postDelayed(Stoprunnable,0);

        if(controlSuccess){
            cicleColor = 0xFF0586FB;//0xFF006CFF
            controlTimeDelay = 3000;
        }else{
            cicleColor = 0xFFFF0000;//0xFF006CFF
            controlTimeDelay = 6000;
        }

        if (cbOnTriggerListener != null){
            if(hasTrigle){
                hasTrigle = false;
                cbOnTriggerListener.trigger();
                isControlButtonRun = false;
                setProgress(0);
                handler.removeCallbacks(Stoprunnable);
            }
        }


        /*new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                isControlButtonRun = false;
                setProgress(0);
                handler.removeCallbacks(Stoprunnable);
            }
        },controlTimeDelay);*/
    }




    public void setCircleBackColor(int circleBackColor) {
        this.circleBackColor = circleBackColor;
        invalidate();
    }

    public boolean isControlButtonRun() {
        return isControlButtonRun;
    }

    public void setControlButtonRun(boolean controlButtonRun) {
        isControlButtonRun = controlButtonRun;
    }
}

相關文章