酷炫進度條 自定義SeekBar
阿新 • • 發佈:2019-02-14
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