自定義圓形progressbar(包含進度動畫效果)
效果圖敬上:)
attrs檔案:
< resources>
< declare-styleable name=”CircleProgressBarStyle”>
< attr name=”circleColor” format=”color”/>
< attr name=”circleProgressColor” format=”color”/>
< attr name=”progressWidth” format=”float”/>
< attr name=”progress” format=”integer”/>
< attr name=”max” format=”integer”/>
< attr name=”progressPadding” format=”integer”/>
< attr name=”animation” format=”boolean”/>
< attr name=”style”>
< enum name=”STROKE” value=”0”/>
< enum name=”FILL” value=”1”/>
< /attr>
< /declare-styleable>
< /resources>
xml檔案:記著加 xmlns:progress=”http://schemas.android.com/apk/res-auto”
< com.test.ffmpeg.CircleProgressBar android:id="@+id/CircleProgressBar" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" progress:circleColor="@color/white" progress:circleProgressColor="@color/colorAccent" progress:progressWidth="10" progress:progressPadding="15" progress:progress="50" progress:max="100" progress:animation="true" progress:style="FILL"/>
CircleProgressBar:
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.os.Message; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * 自定義圓形progressbar */ public class CircleProgressBar extends View { /** * 畫筆 */ private Paint mPaint; /** * 實心圓顏色 */ private int CircleColor; /** * 圓環顏色 */ private int CircleProgressColor; /** * 圓環寬度 */ private float CircleProgressWidth; /** * 實心圓與環間的距離 */ private int ProgressPadding; /** * 最大進度 */ private int ProgressMax; /** * 進度的風格,是否繪畫內部實心圓 */ private int style; /** * 當前進度 */ private int progress; /** * 顯示時是否需要動畫效果 */ private boolean animation; /** * 進度動畫更新次數 */ private int speed = 100;//這裡修改的話每隔10ms處也應修該,個人感覺這個值正好! private double progress_=0;//臨時儲存double型別格式的進度 private int temporaryProgress=0;//臨時存放記錄的progress private double temporary=0; private boolean isFirst=true;//是否是第一次繪製 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if(speed>=0) { speed--; progress_ = progress_ + temporary; if(progress_>=temporaryProgress){ progress=temporaryProgress; }else { progress= (int) progress_; } setProgress(progress); mHandler.sendEmptyMessageDelayed(1, 10);//每隔10ms執行一次 }else { mHandler.removeMessages(1); } } }; public CircleProgressBar(Context context) { this(context, null); } public CircleProgressBar(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0);//!!! } public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); //獲取自定義屬性值 TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBarStyle); CircleColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleColor, Color.WHITE); CircleProgressColor = mTypedArray.getColor(R.styleable.CircleProgressBarStyle_circleProgressColor, Color.BLUE); CircleProgressWidth = mTypedArray.getFloat(R.styleable.CircleProgressBarStyle_progressWidth, 5); ProgressMax = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_max, 100); style = mTypedArray.getInt(R.styleable.CircleProgressBarStyle_style, 1); progress = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progress, 60); ProgressPadding = mTypedArray.getInteger(R.styleable.CircleProgressBarStyle_progressPadding, 0); animation = mTypedArray.getBoolean(R.styleable.CircleProgressBarStyle_animation, false); mTypedArray.recycle(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //開始繪製 內部實心圓 int circle_x = getWidth() / 2;//獲取圓心座標 int radius = (int) (circle_x - CircleProgressWidth - ProgressPadding); int prgress_radius = (int) (circle_x - CircleProgressWidth); if (style == 1) {//判斷是否繪畫內部實心圓 mPaint.setColor(CircleColor);//畫筆顏色 mPaint.setStyle(Paint.Style.FILL);//實心 mPaint.setAntiAlias(true);//消除鋸齒 canvas.drawCircle(circle_x, circle_x, radius, mPaint); } //progressbar進度條(扇形環) RectF rectF = new RectF(circle_x - prgress_radius, circle_x - prgress_radius, circle_x + prgress_radius, circle_x + prgress_radius); mPaint.setColor(CircleProgressColor); mPaint.setStyle(Paint.Style.STROKE);//空心 mPaint.setStrokeWidth(CircleProgressWidth);//圓環寬度 mPaint.setAntiAlias(true);//消除鋸齒 if (animation && isFirst) { isFirst=false; temporary=(double) progress/speed;//設定每次progress增量值 Log.e("增量",""+temporary); temporaryProgress=progress;//記錄 progress=0;//歸0 mHandler.sendEmptyMessage(1); } canvas.drawArc(rectF, -90, 360 * progress / ProgressMax, false, mPaint); } public int getCircleColor() { return CircleColor; } public void setCircleColor(int circleColor) { CircleColor = circleColor; } public int getCircleProgressColor() { return CircleProgressColor; } public void setCircleProgressColor(int circleProgressColor) { CircleProgressColor = circleProgressColor; } public float getCircleProgressWidth() { return CircleProgressWidth; } public void setCircleProgressWidth(float circleProgressWidth) { CircleProgressWidth = circleProgressWidth; } public int getProgressPadding() { return ProgressPadding; } public void setProgressPadding(int progressPadding) { ProgressPadding = progressPadding; } public int getProgressMax() { return ProgressMax; } public void setProgressMax(int progressMax) { if (progressMax > 0) ProgressMax = progressMax; } public int getStyle() { return style; } public void setStyle(int style) { this.style = style; } public synchronized int getProgress() { return progress; } /** * 加個鎖,防止屬性animation和外部同時呼叫該方法異常 * * @param progress */ public synchronized void setProgress(int progress) { if (progress > 0) this.progress = progress > ProgressMax ? ProgressMax : progress; postInvalidate(); } public boolean isAnimation() { return animation; } public void setAnimation(boolean animation) { this.animation = animation; } }