Android實(shí)現(xiàn)環(huán)形進(jìn)度條
一個(gè)通俗易懂的環(huán)形進(jìn)度條,可以定制顏色角度,監(jiān)聽進(jìn)度。
定義一個(gè)attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CircleProgressView"> <!--畫筆寬度--> <attr name="progress_width" format="dimension" /> <!--畫筆顏色--> <attr name="progress_color" format="color" /> <!--加載進(jìn)度起始位置--> <attr name="location_start" format="enum"> <enum name="left" value="1" /> <enum name="top" value="2" /> <enum name="right" value="3" /> <enum name="bottom" value="4" /> </attr> </declare-styleable> </resources>
自定義CircleProgressView
package com.sample.circleprogressview.widget; import android.animation.ValueAnimator; 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.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.view.animation.LinearInterpolator; import com.sample.circleprogressview.R; /** * 普通環(huán)形進(jìn)度條 */ public class CircleProgressView extends View { private int mCurrent;//當(dāng)前進(jìn)度 private Paint mBgPaint;//背景弧線paint private Paint mProgressPaint;//進(jìn)度Paint private float mProgressWidth;//進(jìn)度條寬度 private int mProgressColor = Color.RED;//進(jìn)度條顏色 private int locationStart;//起始位置 private float startAngle;//開始角度 private ValueAnimator mAnimator; public CircleProgressView(Context context) { this(context, null); } public CircleProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView); locationStart = typedArray.getInt(R.styleable.CircleProgressView_location_start, 1); mProgressWidth = typedArray.getDimension(R.styleable.CircleProgressView_progress_width, dp2px(context, 4)); mProgressColor = typedArray.getColor(R.styleable.CircleProgressView_progress_color, mProgressColor); typedArray.recycle(); //背景圓弧 mBgPaint = new Paint(); mBgPaint.setAntiAlias(true); mBgPaint.setStrokeWidth(mProgressWidth); mBgPaint.setStyle(Paint.Style.STROKE); mBgPaint.setColor(Color.parseColor("#eaecf0")); mBgPaint.setStrokeCap(Paint.Cap.ROUND); //進(jìn)度圓弧 mProgressPaint = new Paint(); mProgressPaint.setAntiAlias(true); mProgressPaint.setStyle(Paint.Style.STROKE); mProgressPaint.setStrokeWidth(mProgressWidth); mProgressPaint.setColor(mProgressColor); mProgressPaint.setStrokeCap(Paint.Cap.ROUND); //進(jìn)度條起始角度 if (locationStart == 1) {//左 startAngle = -180; } else if (locationStart == 2) {//上 startAngle = -90; } else if (locationStart == 3) {//右 startAngle = 0; } else if (locationStart == 4) {//下 startAngle = 90; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int size = width < height ? width : height; setMeasuredDimension(size, size); } /** * oval // 繪制范圍 * startAngle // 開始角度 * sweepAngle // 掃過角度 * useCenter // 是否使用中心 */ @Override protected void onDraw(Canvas canvas) { //繪制背景圓弧 RectF rectF = new RectF(mProgressWidth / 2, mProgressWidth / 2, getWidth() - mProgressWidth / 2, getHeight() - mProgressWidth / 2); canvas.drawArc(rectF, 0, 360, false, mBgPaint); //繪制當(dāng)前進(jìn)度 float sweepAngle = 360 * mCurrent / 100; canvas.drawArc(rectF, startAngle, sweepAngle, false, mProgressPaint); } public int getCurrent() { return mCurrent; } /** * 設(shè)置進(jìn)度 * * @param current */ public void setCurrent(int current) { mCurrent = current; invalidate(); } private int tCurrent = -1; /** * 動畫效果 * * @param current 精度條進(jìn)度:0-100 * @param duration 動畫時(shí)間 */ public void startAnimProgress(int current, int duration) { mAnimator = ValueAnimator.ofInt(0, current); mAnimator.setDuration(duration); mAnimator.setInterpolator(new LinearInterpolator()); mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int current = (int) animation.getAnimatedValue(); if (tCurrent != current) { tCurrent = current; setCurrent(current); if (mOnAnimProgressListener != null) mOnAnimProgressListener.valueUpdate(current); } } }); mAnimator.start(); } public interface OnAnimProgressListener { void valueUpdate(int progress); } private OnAnimProgressListener mOnAnimProgressListener; /** * 監(jiān)聽進(jìn)度條進(jìn)度 * * @param onAnimProgressListener */ public void setOnAnimProgressListener(OnAnimProgressListener onAnimProgressListener) { mOnAnimProgressListener = onAnimProgressListener; } public void destroy() { if (mAnimator != null) { mAnimator.cancel(); } } public static int dp2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }
代碼就這么些,接下來我們測算一下
package com.sample.circleprogressview; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.sample.circleprogressview.widget.CircleProgressView; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private CircleProgressView circle_progress; private TextView tv_progress; private Button btn_start; private Button btn_reset; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_start = (Button) findViewById(R.id.btn_start); btn_reset = (Button) findViewById(R.id.btn_reset); circle_progress = (CircleProgressView) findViewById(R.id.circle_progress); tv_progress = (TextView) findViewById(R.id.tv_progress); btn_start.setOnClickListener(this); btn_reset.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_start: //開鎖執(zhí)行動畫效果 circle_progress.startAnimProgress(50, 1200); //監(jiān)聽進(jìn)度條進(jìn)度 circle_progress.setOnAnimProgressListener(new CircleProgressView.OnAnimProgressListener() { @Override public void valueUpdate(int progress) { tv_progress.setText(String.valueOf(progress)); } }); break; case R.id.btn_reset: circle_progress.setCurrent(0); tv_progress.setText("0"); break; } } @Override protected void onDestroy() { super.onDestroy(); if (circle_progress != null) { circle_progress.destroy(); } } }
源碼:下載地址
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android自定義環(huán)形LoadingView效果
- Android自定義View實(shí)現(xiàn)環(huán)形進(jìn)度條的思路與實(shí)例
- Android實(shí)現(xiàn)計(jì)步進(jìn)度的環(huán)形Progress
- Android實(shí)現(xiàn)環(huán)形進(jìn)度條的實(shí)例
- Android實(shí)現(xiàn)環(huán)形進(jìn)度條代碼
- Android應(yīng)用中炫酷的橫向和環(huán)形進(jìn)度條的實(shí)例分享
- Android中制作進(jìn)度框和環(huán)形進(jìn)度條的簡單實(shí)例分享
- Android環(huán)形進(jìn)度條(安卓默認(rèn)形式)實(shí)例代碼
- android自定義環(huán)形對比圖效果
相關(guān)文章
Android開發(fā)筆記 Handler使用總結(jié)
當(dāng)應(yīng)用程序啟動時(shí),Android首先會開啟一個(gè)主線程(也就是UI線程),主線程為管理界面中的UI控件,進(jìn)行事件分發(fā)2012-11-11Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法示例
這篇文章主要介紹了Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法,結(jié)合實(shí)例形式分析了Android基于OpenGL的圖形繪制技巧,需要的朋友可以參考下2016-10-10Android從Fragment跳轉(zhuǎn)到其他Activity的簡單實(shí)例
這篇文章主要介紹了Android從Fragment跳轉(zhuǎn)到其他Activity的簡單實(shí)例,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02Android開發(fā)教程之調(diào)用攝像頭功能的方法詳解
這篇文章主要介紹了Android調(diào)用攝像頭功能的方法,詳細(xì)分析了Android調(diào)用攝像頭功能的權(quán)限設(shè)置、功能代碼與實(shí)現(xiàn)步驟,需要的朋友可以參考下2016-06-06Android連接MySQL數(shù)據(jù)庫詳細(xì)教程
在Android應(yīng)用程序中連接 MySQL 數(shù)據(jù)庫可以幫助開發(fā)人員實(shí)現(xiàn)更豐富的數(shù)據(jù)管理功能,本教程將介紹如何在Android應(yīng)用程序中使用低版本的MySQL Connector/J驅(qū)動程序來連接MySQL數(shù)據(jù)庫,需要的朋友可以參考下2023-05-05Android屬性動畫實(shí)現(xiàn)布局的下拉展開效果
這篇文章主要為大家詳細(xì)介紹了Android屬性動畫實(shí)現(xiàn)布局的下拉展開效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07