Android自定義View實現(xiàn)圓形進度條
更新時間:2020年10月27日 13:19:00 作者:迷路國王
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)圓形進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Android自定義View實現(xiàn)圓形進度條的具體代碼,供大家參考,具體內(nèi)容如下
效果如下:
主要代碼
CircularProgressView.java
public class CircularProgressView extends View { private Paint mBackPaint, mProgPaint; // 繪制畫筆 private RectF mRectF; // 繪制區(qū)域 private int[] mColorArray; // 圓環(huán)漸變色 private int mProgress; // 圓環(huán)進度(0-100) /** * 繪制弧線的畫筆 */ private Paint progressPaint; /** * 圓弧圓心位置 */ private int centerX, centerY; /** * 圓弧的半徑 */ private int circleRadius; public CircularProgressView(Context context) { this(context, null); } public CircularProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CircularProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @SuppressLint("Recycle") TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView); // 初始化背景圓環(huán)畫筆 mBackPaint = new Paint(); mBackPaint.setStyle(Paint.Style.STROKE); // 只描邊,不填充 mBackPaint.setStrokeCap(Paint.Cap.ROUND); // 設置圓角 mBackPaint.setAntiAlias(true); // 設置抗鋸齒 mBackPaint.setDither(true); // 設置抖動 mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5)); mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progbgColor, Color.LTGRAY)); // 初始化進度圓環(huán)畫筆 mProgPaint = new Paint(); mProgPaint.setStyle(Paint.Style.STROKE); // 只描邊,不填充 mProgPaint.setStrokeCap(Paint.Cap.ROUND); // 設置圓角 mProgPaint.setAntiAlias(true); // 設置抗鋸齒 mProgPaint.setDither(true); // 設置抖動 mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10)); mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE)); //初始化結(jié)束位置小圓點 progressPaint = new Paint(); progressPaint.setStyle(Paint.Style.FILL); // 填充 progressPaint.setStrokeCap(Paint.Cap.ROUND); // 設置圓角 progressPaint.setAntiAlias(true); // 設置抗鋸齒 progressPaint.setDither(true); // 設置抖動 progressPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10)); progressPaint.setColor(Color.WHITE); // 初始化進度圓環(huán)漸變色 int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1); int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1); if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor}; else mColorArray = null; // 初始化進度 mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0); typedArray.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth())); int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2; int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2; mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength); centerX = getMeasuredWidth() / 2; centerY = getMeasuredHeight() / 2; //計算圓弧半徑和圓心點 circleRadius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2; circleRadius-=8; // 設置進度圓環(huán)漸變色 if (mColorArray != null && mColorArray.length > 1) mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawArc(mRectF, 0, 360, false, mBackPaint); canvas.drawArc(mRectF, 270, 360 * mProgress / 100, false, mProgPaint); //繪制結(jié)束位置小圓形 progressPaint.setStrokeWidth(10); progressPaint.setStyle(Paint.Style.FILL); float swipe = 360 * mProgress / 100; Log.d("=================", swipe + " mProgress"); float radians = (float) (((swipe - 90) / 2) / 180 * 2 * Math.PI); float endX; float endY; endX = centerX + circleRadius * (float) Math.cos(radians); endY = centerY + circleRadius * (float) Math.sin(radians); if (mProgress!=0) { canvas.drawCircle(endX, endY, 8, progressPaint); } } /** * 獲取當前進度 * * @return 當前進度(0-100) */ public int getProgress() { return mProgress; } /** * 設置當前進度 * * @param progress 當前進度(0-100) */ public void setProgress(int progress) { this.mProgress = progress; invalidate(); } /** * 設置當前進度,并展示進度動畫。如果動畫時間小于等于0,則不展示動畫 * * @param progress 當前進度(0-100) * @param animTime 動畫時間(毫秒) */ public void setProgress(int progress, long animTime) { if (animTime <= 0) setProgress(progress); else { ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mProgress = (int) animation.getAnimatedValue(); invalidate(); } }); animator.setInterpolator(new OvershootInterpolator()); animator.setDuration(animTime); animator.start(); } } /** * 設置背景圓環(huán)寬度 * * @param width 背景圓環(huán)寬度 */ public void setBackWidth(int width) { mBackPaint.setStrokeWidth(width); invalidate(); } /** * 設置背景圓環(huán)顏色 * * @param color 背景圓環(huán)顏色 */ public void setBackColor(/*@ColorRes int color*/String color) { mBackPaint.setColor(Color.parseColor(color)); //畫筆顏色 invalidate(); } /** * 設置進度圓環(huán)寬度 * * @param width 進度圓環(huán)寬度 */ public void setProgWidth(int width) { mProgPaint.setStrokeWidth(width); invalidate(); } /** * 設置進度圓環(huán)顏色 * * @param color 景圓環(huán)顏色 */ public void setProgColor(/*@ColorRes int color*/String color) { mProgPaint.setColor(Color.parseColor(color)); //畫筆顏色 mProgPaint.setShader(null); invalidate(); } /** * 設置進度圓環(huán)顏色(支持漸變色) * * @param startColor 進度圓環(huán)開始顏色 * @param firstColor 進度圓環(huán)結(jié)束顏色 */ public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) { mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)}; mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR)); invalidate(); } /** * 設置進度圓環(huán)顏色(支持漸變色) * * @param colorArray 漸變色集合 */ public void setProgColor(@ColorRes int[] colorArray) { if (colorArray == null || colorArray.length < 2) return; mColorArray = new int[colorArray.length]; for (int index = 0; index < colorArray.length; index++) mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]); mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR)); invalidate(); } }
attrs.xml
<declare-styleable name="CircularProgressView"> <attr name="backWidth" format="dimension" /> <!--背景圓環(huán)寬度--> <attr name="progWidth" format="dimension" /> <!--進度圓環(huán)寬度--> <attr name="progbgColor" format="color" /> <!--背景圓環(huán)顏色--> <attr name="progColor" format="color" /> <!--進度圓環(huán)顏色--> <attr name="progStartColor" format="color" /> <!--進度圓環(huán)開始顏色--> <attr name="progFirstColor" format="color" /> <!--進度圓環(huán)結(jié)束顏色--> <attr name="progress" format="integer" /> <!--圓環(huán)進度--> </declare-styleable>
使用方法
<com.view.CircularProgressView android:layout_width="170dp" android:layout_height="170dp" android:layout_centerInParent="true" android:layout_centerHorizontal="true" app:backWidth="5dp" app:progWidth="5dp" app:progbgColor="#4C5098" app:progress="50" android:layout_marginTop="500dp" />
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Service服務不被停止詳解及實現(xiàn)
這篇文章主要介紹了Android Service服務不被停止詳解及實現(xiàn)的相關(guān)資料,有很多應用在設置運行中會被直接停止掉,這里就提供一個方法一直運行,需要的朋友可以參考下2016-11-11Kotlin語言使用BroadcastReceiver示例介紹
Android開發(fā)的四大組件分別是:活動(activity),用于表現(xiàn)功能;服務(service),后臺運行服務,不提供界面呈現(xiàn);廣播接受者(Broadcast Receive),勇于接收廣播;內(nèi)容提供者(Content Provider),支持多個應用中存儲和讀取數(shù)據(jù),相當于數(shù)據(jù)庫,本篇著重介紹廣播組件2022-09-09基于Android MarginLeft與MarginStart的區(qū)別(詳解)
下面小編就為大家分享一篇基于Android MarginLeft與MarginStart的區(qū)別(詳解),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12