1. 程式人生 > >酷炫進度條 自定義SeekBar

酷炫進度條 自定義SeekBar

package com.totcy.magicprogress;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

/**
 * Description 圓形裝逼進度條
 * Author: tu
 * Date: 2016-08-19
 * Time: 14:33
 */
public class CircleProgress extends View{

	private float textSize = getResources().getDimension(R.dimen.text_size_14);
    private float dotX, dotY;//圓點xy
    private int viewWidth;//view的寬度
    private int viewHigth;//view的高度
    private Paint mPaint,mPaintArc;//畫筆  212 62 96
    private int colorBg = Color.argb(255,54,68,76);//背景圓顏色
    private int colorWhite = Color.argb(255,255,255,255);//文字顏色
    private int colorBlack = Color.argb(255,34,49,59);//第二刻度顏色
    private int colorBlue = Color.argb(255,94,248,249);//刻度顏色
    private int pandding = 10;
    private RectF rectF;
    private float radius = 10;//半徑
    private float scaleLineLenth = 3;//刻度線長
    private int scaleAngle = 10;//刻度間隔
    private int scaleWidth = 5;//刻度寬度
    private int curProgress = 0;//0 ~ 100進度 當前進度
    private int oldProgress = 0;

	public void setColorBlue(int colorBlue) {
		this.colorBlue = colorBlue;
	}

	public void setTextSize(float textSize) {
		this.textSize = textSize;
	}

	public int getCurProgress() {
        return curProgress;
    }

    public void setCurProgress(int curProgress) {
        this.curProgress = curProgress;
        invalidate();
    }

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

    public CircleProgress(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化畫筆
     */
    private void init(Context context) {

        //初始化座標畫筆
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//
        mPaintArc = new Paint(Paint.ANTI_ALIAS_FLAG);//
        mPaint.setColor(colorWhite);
        mPaintArc.setColor(colorBg);
        mPaint.setAntiAlias(true);
        mPaintArc.setAntiAlias(true);
        mPaint.setTextSize(15);
        mPaint.setStyle(Paint.Style.STROKE);//空心
        //當前進度

    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int height;
        int width;

        //寬度測量
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            width = getMeasuredWidth();
        }
        dotX = width / 2;
        viewWidth = width;
        //高度測量
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = getMeasuredHeight();
        }
        viewHigth = height;
        dotY = height / 2;
        radius = dotX-(getPaddingLeft() + getPaddingRight())/2;
        scaleLineLenth = radius/3;
        rectF = new RectF(dotX - radius, dotY - radius, dotX + radius, dotY + radius);
        setMeasuredDimension(width, height);
    }
    private void drawProgress(Canvas canvas){
    	if(mPaintArc == null){
    		return;
    	}
        //圓
        mPaintArc.setStyle(Paint.Style.FILL);
        canvas.drawCircle(dotX, dotY, radius, mPaintArc);
        //中心進度值
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//實心
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setStrokeWidth(1);
        mPaint.setTextSize(textSize);
        mPaint.setColor(colorWhite);
        canvas.drawText(curProgress + "%",dotX,
                dotY+getResources().getDimension(R.dimen.text_size_14)/2
                ,mPaint);
        //黑色刻度  12點鐘方向為起始點(-90°),正時針方法繪製
        for (int angle = -90; angle <= 270; angle += scaleAngle){
            float xY[] = caculCoordinate(angle);
            if(xY != null) {
                mPaint.setStrokeWidth(scaleWidth);
                mPaint.setColor(colorBlack);
                canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint);
            }
        }
        //進度演算法
        //360 除與 scaleAngle(進度間隔10) = 36; 再拿進度總數100換算當前進度
        //算出當前進度佔幾個刻度
        int curProgressCount = curProgress * (360/scaleAngle) /100;
        int angleStart = -90;
        for (int count = 0; count < curProgressCount;count ++){
            float xY[] = caculCoordinate(angleStart);
            if(xY != null) {
                mPaint.setStrokeWidth(scaleWidth);
                mPaint.setColor(colorBlue);
                canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint);
            }
            angleStart += scaleAngle;
        }

    }

    /**
     * 根據圓心角 計算圓周上的座標
     * @param angle
     * @return xY[0] startX; xY[1] startY; xY[2] endX; xY[3] endY;
     */
    private float[] caculCoordinate(int angle){
        //angle >180     angle = angle -180
        float xY[] = new float[4];
        //角度處理
        int tempAngle = Math.abs(angle);
        float tempScaleLineLenth = scaleLineLenth;

         if(270 > tempAngle && tempAngle >= 180) {
            tempAngle = tempAngle - 180;
            xY[0] = dotX - getCoordinateX(tempAngle,radius);
            xY[1] = dotY - getCoordinateY(tempAngle,radius);

            xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth);
            xY[3] = xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth);
        }else if(180 > tempAngle && tempAngle > 90){
            tempAngle = 180 - tempAngle;
            xY[0] = dotX - getCoordinateX(tempAngle,radius);
            xY[1] = dotY + getCoordinateY(tempAngle,radius);

            xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth);
            xY[3] = xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth);
        }else if(90 >= tempAngle && tempAngle >= 0){
            xY[0] = dotX + getCoordinateX(tempAngle,radius);
            xY[1] = angle < 0 ? dotY - getCoordinateY(tempAngle,radius) : dotY + getCoordinateY(tempAngle,radius);

            xY[2] = xY[0] - getCoordinateX(tempAngle,tempScaleLineLenth);
            xY[3] = angle < 0 ? xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth) : xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth);
        }

        return xY;
    }


    /**
     * 獲取圓周上y值相對值
     * @param tempAngle
     * @param radius 算開始座標是傳半徑,算結束座標時傳刻度線的長度
     * @return
     */
    private float getCoordinateY(int tempAngle,float radius){

        //利用正弦函式算出y座標
        return (float) (Math.sin(tempAngle*Math.PI/180)*(radius - 15)); //10 是離圓弧的距離
    }
    /**
     * 獲取圓周上X值相對值
     * @param tempAngle
     * @return
     */
    private float getCoordinateX(int tempAngle,float radius){

        //利用餘弦函式算出y座標
        return (float) (Math.cos(tempAngle*Math.PI/180)*(radius - 15));
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawProgress(canvas);
    }
    public void setProgress(int progress){
        if (progress < 0 || progress > 100)
            return;
        ObjectAnimator o = ObjectAnimator.ofInt(this, "curProgress", oldProgress, progress);
        o.setDuration(1000);
        o.setInterpolator(new DecelerateInterpolator());
        o.start();
        oldProgress = progress;
    }
}

組合起來使用:MyProgress.class