自定義弧形漸變進度條功能
阿新 • • 發佈:2019-01-07
/** * 畫筆物件的引用 */ private Paint paint; private Paint smallcicrlPaint; /** 分段顏色 */ private static final int[] SECTION_COLORS = { Color.BLUE, Color.YELLOW, Color.RED }; /** * 圓環的顏色 */ private int roundColor; /** * 圓環進度的顏色 */ private int roundProgressColor; /** * 中間進度百分比的字串的顏色 */ private int textColor; /** * 中間進度百分比的字串的字型 */ private float textSize; /** * 圓環的寬度 */ private float roundWidth; /** * 最大進度 */ private int max; /** * 當前進度 */ private int progress; /** * 是否顯示中間的進度 */ private boolean textIsDisplayable; /** * 進度的風格,實心或者空心 */ private int style; public static final int STROKE = 0; public static final int FILL = 1; private boolean isDrawBG = false; private Context mContext; public boolean isDrawBG() { return isDrawBG; } public void setDrawBG(boolean isDrawBG) { this.isDrawBG = isDrawBG; } public RoundProgressBar(Context context) { this(context, null); } public RoundProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; paint = new Paint(); smallcicrlPaint = new Paint(); TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar); // 獲取自定義屬性和預設值 roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED); roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN); textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN); textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15); roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 20); roundWidth = context.getResources().getDimension(R.dimen.incall_round_progress_width); max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100); textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true); style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0); mTypedArray.recycle(); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 畫最外層的大圓環 */ int centre = getWidth() / 2; // 獲取圓心的x座標 int radius = (int) (centre - roundWidth / 2 - 20); // 圓環的半徑 paint.setColor(Color.parseColor("#DDDDDD")); // 設定圓環的顏色 paint.setStyle(Paint.Style.STROKE); // 設定空心 paint.setStrokeWidth(roundWidth); // 設定圓環的寬度 paint.setAntiAlias(true); // 消除鋸齒 PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1); paint.setPathEffect(effects); paint.setShader(null); RectF oval = new RectF(centre - radius, centre - radius, (centre + radius), centre + radius); // 用於定義的圓弧的形狀和大小的界限 if (isDrawBG) { // canvas.drawCircle(centre, centre, radius, paint); // 畫出圓環 canvas.drawArc(oval, 150, 240 * 1, false, paint); // 根據進度畫圓弧 } /** * 畫小圓邊線 */ smallcicrlPaint.setColor(Color.parseColor("#DDDDDD")); // 設定圓環的顏色 smallcicrlPaint.setStyle(Paint.Style.STROKE); // 設定空心 smallcicrlPaint.setStrokeWidth(Util.px2dip(mContext, 5)); // 設定圓環的寬度 smallcicrlPaint.setAntiAlias(true); // 消除鋸齒 int width = MyShareprefrence.getInstance(mContext).getScreenWidth(); if (width < 720) { width = 10; } else { width = 25; } RectF smalloval = new RectF(centre - radius + width, centre - radius + width, (centre + radius - width), centre + radius - width); // canvas.drawCircle(centre, centre, radius - 25, smallcicrlPaint); // 畫出圓環 canvas.drawArc(smalloval, 150, 240 * 1, false, smallcicrlPaint); // 根據進度畫圓弧 /** * 畫進度百分比 */ // paint.setStrokeWidth(0); // paint.setColor(textColor); // paint.setTextSize(textSize); // paint.setTypeface(Typeface.DEFAULT_BOLD); // 設定字型 // int percent = (int) (((float) progress / (float) max) * 100); // // 中間的進度百分比,先轉換成float在進行除法運算,不然都為0 // float textWidth = paint.measureText(percent + "%"); // // 測量字型寬度,我們需要根據字型的寬度設定在圓環中間 // // if (textIsDisplayable && percent != 0 && style == STROKE) { // paint.setTextSize(30); // canvas.drawText(percent + "分", centre - textWidth / 2 - textSize, // centre + textSize / 2, paint); // 畫出進度百分比 // } /** * 畫圓弧 ,畫圓環的進度 */ // 設定漸變效果 SweepGradient lg = null; float[] positions = new float[] { 0.2f, 0.5f, 0.8f, 1.0f }; // lg = new LinearGradient(0, 0, 100, 100, SECTION_COLORS, null, // Shader.TileMode.MIRROR); lg = new SweepGradient(centre, centre, SECTION_COLORS, null); Matrix matrix = new Matrix(); matrix.setRotate(90, centre, centre);//設定漸變的開始的弧度位置 lg.setLocalMatrix(matrix); paint.setTextSize(textSize); if (lg != null) { paint.setShader(lg); } // 設定進度是實心還是空心 paint.setStrokeWidth(roundWidth); // 設定圓環的寬度 // paint.setColor(roundProgressColor); // 設定進度的顏色 paint.setColor(Color.BLUE);// paint.setPathEffect(null); // 設定進度的顏色 // RectF oval = new RectF(centre - radius, centre - radius, // (centre + radius), centre + radius); // 用於定義的圓弧的形狀和大小的界限 switch (style) { case STROKE: { paint.setStyle(Paint.Style.STROKE); canvas.drawArc(oval, 150, 240 * progress / max, false, paint); // 根據進度畫圓弧 break; } case FILL: { paint.setStyle(Paint.Style.FILL_AND_STROKE); if (progress != 0) { canvas.drawArc(oval, -90, 360 * progress / max, true, paint); // 根據進度畫圓弧 } break; } } } public synchronized int getMax() { return max; } /** * 設定進度的最大值 * * @param max */ public synchronized void setMax(int max) { if (max < 0) { throw new IllegalArgumentException("max not less than 0"); } this.max = max; } /** * 獲取進度.需要同步 * * @return */ public synchronized int getProgress() { return progress; } /** * 設定進度,此為執行緒安全控制元件,由於考慮多線的問題,需要同步 重新整理介面呼叫postInvalidate()能在非UI執行緒重新整理 * * @param progress */ public synchronized void setProgress(int progress) { if (progress < 0) { throw new IllegalArgumentException("progress not less than 0"); } if (progress > max) { progress = max; } if (progress <= max) { this.progress = progress; postInvalidate(); } } public int getCricleColor() { return roundColor; } public void setTextShow(boolean isShow) { textIsDisplayable = isShow; } public void setCricleColor(int cricleColor) { this.roundColor = cricleColor; } public int getCricleProgressColor() { return roundProgressColor; } public void setCricleProgressColor(int cricleProgressColor) { this.roundProgressColor = cricleProgressColor; } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { this.textColor = textColor; } public float getTextSize() { return textSize; } public void setTextSize(float textSize) { this.textSize = textSize; } public float getRoundWidth() { return roundWidth; } public void setRoundWidth(float roundWidth) { this.roundWidth = roundWidth; }
仿iphone帶進度的進度條,執行緒安全的View,可直接線上程中更新進度,加入了漸變的進度條功能, SweepGradient即為掃描/梯度渲染,此處比較重要,很少用到這個方法