Android之自定義可顯示分段顏色的progressBar
阿新 • • 發佈:2019-01-26
本文主要記錄一個自定義progressBar,主要是實現分段顯示不同顏色的ProgressBar
重點為了記錄一下自定義view的過程
1.新建一個class,繼承View或其子類,具體可以繼承哪些類,看這篇,比如類名叫 ProgressbarView ;
2. 編寫屬性檔案,放在values裡,在佈局裡使用時都是需要設定一些相關屬性的,比如
<declare-styleable name="ProgressbarView">裡的name是檔案類名,attr裡是屬性名,佈局檔案裡會這麼使用<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ProgressbarView"> <attr name="p_width" format="dimension"/> <!-- 控制元件寬度 --> <attr name="p_height" format="dimension"/><!-- 控制元件官高度 --> <attr name="p_maxValue" format="integer"/><!-- 控制元件progress最大值 --> <attr name="p_progressValue" format="integer"/><!-- 當前 progress value --> <attr name="p_shapeType" format="enum"><!-- 控制元件型別 矩形,圓,圓角矩形 --> <enum name="rectangle" value="0" /> <enum name="circle" value="1" /> <enum name="square" value="2" /> </attr> <attr name="p_progressColor" format="color"/><!-- progress 進度條顏色 --> <attr name="p_progressBackColor" format="color"/><!-- progress 背景 顏色 --> <attr name="p_progressSegmentColor" format="color"/><!-- progress 分段 顏色 --> <attr name="p_progressDoubleSegColor" format="color"/><!-- progress 分段間隔 顏色 --> <attr name="p_circle_radius" format="dimension"/><!-- 圓 半徑 --> <attr name="p_circle_X_Y" format="dimension"/><!-- 圓 心 橫座標或者縱座標 > 半徑(正方形嘛)--> <attr name="p_showText" format="boolean"/><!-- 是否顯示文字 --> <attr name="p_textSize" format="dimension"/><!-- 文字大小 --> <attr name="p_textLowColor" format="color"/><!-- 1/3 文字顏色 --> <attr name="p_textMiddleColor" format="color"/><!-- 1/3 - 2/3文字顏色 --> <attr name="p_textHighColor" format="color"/><!-- 2/3文字顏色 --> <attr name="p_square_radius" format="dimension"/><!-- 圓角矩形 半徑--> </declare-styleable> </resources>
然後這個檔案在java程式碼裡怎麼使用呢,在我們的view裡,我們需要實現其構造方法,有三個,AttributeSet物件就是用來處理自定義屬性的,直接上程式碼<com.cl.slack.lib.ProgressbarView android:id="@+id/progressbar" android:layout_width="wrap_content" android:layout_height="100dp" app:p_height = "10dp" app:p_width = "300dp" app:p_shapeType="square" app:p_progressColor="#00ff00" app:p_progressBackColor="#777777" app:p_progressSegmentColor="#008800" app:p_progressDoubleSegColor="#770077" app:p_showText = "true" app:p_square_radius="8dp" app:p_textSize="13sp" app:p_textLowColor="#880055" app:p_textMiddleColor="#008855" app:p_textHighColor="#885500" app:p_circle_radius="20dp" app:p_circle_X_Y="30dp" />
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Handler; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.util.ArrayList; import java.util.List; /** * <p>Description: progressbar </p> * Created by slack on 2016/8/1 10:04 . */ public class ProgressbarView extends View { private final int DEFAULT_WIDTH = 450; private final int DEFAULT_HEIGTH = 40; private final int DEFAULT_SHAPE = 0; private final int DEFAULT_MAX = 100; private final int DEFAULT_PROGRESS = 0; private final int DEFAULT_PROGRESS_COLOR = Color.parseColor("#76B034"); private final int DEFAULT_PROGRESS_BACK_COLOR = Color.parseColor("#EFEFEF"); private final int DEFAULT_CIRCLE_R = 50; private final int DEFAULT_SQUARE_R = 20; private final int DEFAULT_TEXT_SIZE = 30; private enum ShapeType{ RECTANGLE, CIRCLE, SQUARE } private int progress = DEFAULT_PROGRESS; private int max = DEFAULT_MAX; private float mwidth = DEFAULT_WIDTH; private float mhight = DEFAULT_HEIGTH; private int mShapeType = DEFAULT_SHAPE; private int proColor = DEFAULT_PROGRESS_COLOR; private int proBackColor = DEFAULT_PROGRESS_BACK_COLOR; private int textLowColor = Color.BLACK; private int textMiddleColor = Color.BLUE; private int textHighColor = Color.RED; private int progressSegmentColor = proColor; private int progressDoubleSegColor = Color.GRAY; private float squareRadius = DEFAULT_SQUARE_R; private float textSize = DEFAULT_TEXT_SIZE; private boolean showText; private float circleX = DEFAULT_CIRCLE_R + 20; private float circleR = DEFAULT_CIRCLE_R; private float startX; private float startY; private float startR = -90; private Paint paint; RectF circleRectf,squareRectf; private List<Integer> progressList; public ProgressbarView(Context context) { this(context,null); } public ProgressbarView(Context context, AttributeSet attrs) { this(context, attrs,0); } public ProgressbarView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context, attrs, defStyleAttr); } private void initView(Context context, AttributeSet attrs, int defStyleAttr) { // Load the styled attributes and set their properties TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.ProgressbarView, defStyleAttr, 0); mwidth = attributes.getDimension(R.styleable.ProgressbarView_p_width, DEFAULT_WIDTH); mhight = attributes.getDimension(R.styleable.ProgressbarView_p_height, DEFAULT_HEIGTH); mShapeType = attributes.getInteger(R.styleable.ProgressbarView_p_shapeType, DEFAULT_SHAPE); showText = attributes.getBoolean(R.styleable.ProgressbarView_p_showText,false); if(mShapeType == 1){ circleR = attributes.getDimension(R.styleable.ProgressbarView_p_circle_radius, DEFAULT_CIRCLE_R); // showText = true; circleX = attributes.getDimension(R.styleable.ProgressbarView_p_circle_X_Y,circleR + 20); } if(mShapeType == 2){ squareRadius = attributes.getDimension(R.styleable.ProgressbarView_p_square_radius,DEFAULT_SQUARE_R); } if(showText){ textSize = attributes.getDimensionPixelSize(R.styleable.ProgressbarView_p_textSize,DEFAULT_TEXT_SIZE); } max = attributes.getInteger(R.styleable.ProgressbarView_p_maxValue, DEFAULT_MAX); progress = attributes.getInteger(R.styleable.ProgressbarView_p_progressValue, DEFAULT_PROGRESS); proColor = attributes.getColor(R.styleable.ProgressbarView_p_progressColor,DEFAULT_PROGRESS_COLOR); proBackColor = attributes.getColor(R.styleable.ProgressbarView_p_progressBackColor,DEFAULT_PROGRESS_BACK_COLOR); textLowColor = attributes.getColor(R.styleable.ProgressbarView_p_textLowColor,Color.BLACK); textMiddleColor = attributes.getColor(R.styleable.ProgressbarView_p_textMiddleColor,Color.BLUE); textHighColor = attributes.getColor(R.styleable.ProgressbarView_p_textHighColor,Color.RED); progressSegmentColor = attributes.getColor(R.styleable.ProgressbarView_p_progressSegmentColor,DEFAULT_PROGRESS_COLOR); progressDoubleSegColor = attributes.getColor(R.styleable.ProgressbarView_p_progressDoubleSegColor,Color.GRAY); Log.i("slack",mwidth + "," + mhight + "," + mShapeType + "," + max + "," + progress + "," + showText + "," + squareRadius + "," + textSize); paint = new Paint(); circleRectf = new RectF(); squareRectf = new RectF(); progressList = new ArrayList<>(); paint.setAntiAlias(true); paint.setFlags(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.parseColor("#EFEFEF")); paint.setStrokeWidth(10); // paint.setStyle(Paint.Style.STROKE); paint.setStyle(Paint.Style.FILL); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setColor(proBackColor); paint.setStrokeWidth(10); paint.setTextSize(textSize); startX = 0; startY = 0; switch (mShapeType){ case 0: canvas.drawRect(startX, startY, mwidth, mhight, paint); paint.setColor(proColor); if(progressList.size() > 0){ for(int pro : progressList){ canvas.drawRect(startX, startY, ((float) pro / max) * mwidth, mhight, paint); startX = ((float) pro/max) * mwidth; // Log.i("slack","startX:" + startX + "," + pro + "," + max +"," + mwidth); paint.setColor(progressSegmentColor); } }else{ canvas.drawRect(startX, startY, ((float) progress / max) * mwidth, mhight, paint); } // paint.setColor(Color.RED); // canvas.drawLine(startX, startY + (mhight - startY) / 4 * 2, // ((float) progress / max) * mwidth, startY + (mhight - startY) // / 4 * 2, paint); paint.setStrokeWidth(1);// paint.setColor(progressDoubleSegColor); if(progressList.size() > 0){ for(int i = 0;i<progressList.size() -1;i++){ canvas.drawLine(((float) progressList.get(i) / max) * mwidth,startY,((float) progressList.get(i) / max) * mwidth, startY + (mhight - startY),paint); } } if(showText){ if(progress<(max/3)){ paint.setColor(textLowColor); }else if(progress<(max/3)*2&&progress>(max/3)){ paint.setColor(textMiddleColor); }else{ paint.setColor(textHighColor); } canvas.drawText(progress + "%", ((float) progress / max) * mwidth - (progress == 0 ? 0 : textSize), mhight + textSize, paint); } break; case 1: paint.setStyle(Paint.Style.STROKE); paint.setColor(proColor); circleRectf.set(circleX,circleX,circleX + circleR * 2,circleX + circleR * 2); if(progressList.size() > 0){ startR = -90; float last = 0; boolean isOu = true; for(int pro : progressList){ canvas.drawArc(circleRectf, startR, ((pro-last) / max) * 360 ,false, paint); startR = ((pro-last) / max) * 360 + startR; last = pro; // Log.i("slack","startR:" + startR); if(isOu){ paint.setColor(progressSegmentColor); }else { paint.setColor(proColor); } isOu = !isOu; } }else{ canvas.drawArc(circleRectf, startR, ((float) progress / max) * 360, false, paint); } if(showText){ paint.reset(); paint.setStrokeWidth(1); paint.setTextSize(textSize); if(progress<(max/3)){ paint.setColor(textLowColor); }else if(progress<(max/3)*2&&progress>(max/3)){ paint.setColor(textMiddleColor); }else{ paint.setColor(textHighColor); } if (progress == max) { canvas.drawText("done", circleX + textSize/2f ,circleX + textSize *2f , paint); } else { canvas.drawText(progress + "%", circleX + textSize/2f ,circleX + textSize*2f , paint); } } break; case 2: squareRectf.set(startX, startY, mwidth, mhight); canvas.drawRoundRect(squareRectf,squareRadius,squareRadius,paint); paint.setColor(proColor); if(progressList.size() > 0){ for(int pro : progressList){ squareRectf.set(startX, startY, ((float) pro / max) * mwidth,mhight); canvas.drawRoundRect(squareRectf,squareRadius,squareRadius,paint); startX = ((float) pro/max) * mwidth; // Log.i("slack","startX:" + startX + "," + pro + "," + max +"," + mwidth); paint.setColor(progressSegmentColor); } }else{ squareRectf.set(startX, startY, ((float) progress / max) * mwidth,mhight); canvas.drawRoundRect(squareRectf,squareRadius,squareRadius,paint); } paint.setColor(progressDoubleSegColor); paint.setStrokeWidth(1); if(progressList.size() > 0){ for(int i = 0;i<progressList.size() -1;i++){ canvas.drawLine(((float) progressList.get(i) / max) * mwidth,startY,((float) progressList.get(i) / max) * mwidth, startY + (mhight - startY),paint); } } if(showText){ if(progress<(max/3)){ paint.setColor(textLowColor); }else if(progress<(max/3)*2&&progress>(max/3)){ paint.setColor(textMiddleColor); }else{ paint.setColor(textHighColor); } canvas.drawText(progress + "%", ((float) progress / max) * mwidth - (progress == 0 ? 0 : textSize), mhight + textSize, paint); } break; default:break; } } // - - - - - - - - - - - - - public - - - - - - - - - - - - - - - - - public int getProgress() { return progress; } public void setProgress(int progress) { setProgress(progress,false); } public void setProgress(int progress,boolean needDel) { if(progress <= max){ this.progress = progress; if(needDel){ progressList.add(progress); } invalidate(); } } public void removeProgress(int progres) { if(progressList.size() > 0){ progressList.remove(progressList.size() - 1 ); if(progressList.size() == 0){ progress = DEFAULT_PROGRESS; }else { progress = progressList.get(progressList.size() - 1); } }else{ progress = progres; } invalidate(); } }
主要工作都在onDraw裡完成,就是各種繪製嘛,東西不難,主要記錄一個過程
- - - - - - - - - - - - 更新 增加倒計時功能 - - - - - - - - - - - - - - - - - - - - - -
功能與這個一樣,看看效果,專案地址不變