Android自定义圆形进度条

来源:互联网 发布:半条命2剧情知乎 编辑:程序博客网 时间:2024/05/16 08:33

Android自定义圆形进度条,效果图如下:


主要逻辑如下:

RoundProgressBar.java

package com.jackie.roundprogressbar;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.graphics.Typeface;import android.util.AttributeSet;import android.view.View;/** * 仿iphone带进度的进度条,线程安全的View,可直接在线程中更新进度 * @author Jackie * */public class RoundProgressBar extends View {private Paint mPaint;  //画笔对象private int mRoundColor; //圆环的颜色private int mRoundProgressColor; //圆形进度的颜色private int mTextColor;  //中间进度百分比的字符串的颜色private float mTextSize; //中间进度百分比的字符串的字体private float mRoundWidth; //圆环的宽度private float mProgress;  //当前进度private int mMax;  //最大进度private boolean mTextIsDisplayable; //是否显示中间的进度private int mStyle; //进度的风格,实心或者空心private static final int STROKE = 0;private static final int FILL = 1;public RoundProgressBar(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint();TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);//获取自定义属性和默认值mRoundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);mRoundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);mTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textRColor, Color.GREEN);mTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textRSize, 15);mRoundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);mMax = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);mTextIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);mStyle = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);mTypedArray.recycle();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画最外层的大圆环int center = getWidth() / 2;  //获取圆心的x坐标int radius = (int) (center - mRoundWidth / 2); //圆环的半径mPaint.setColor(mRoundColor); //设置圆环的颜色mPaint.setStyle(Paint.Style.STROKE); //设置空心mPaint.setStrokeWidth(mRoundWidth);mPaint.setAntiAlias(true); //消除据此canvas.drawCircle(center, center, radius, mPaint); //画出圆环//画进度百分比mPaint.setStrokeWidth(0);mPaint.setColor(mTextColor);mPaint.setTextSize(mTextSize);mPaint.setTypeface(Typeface.DEFAULT);  //设置字体int percent = (int)(((float)mProgress / (float)mMax) * 100); //中间的进度百分比,先转换成float在进行除法运算,不然都为0float textWidth = mPaint.measureText("PVideo");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间if (mTextIsDisplayable && percent != 0 && mStyle == STROKE) {//画出进度百分比canvas.drawText("   " + percent + "%", center - textWidth / 2, center + mTextSize / 2, mPaint);}//画圆弧,画圆环的进度//设置进度是实心还是空心mPaint.setStrokeWidth(mRoundWidth);  //设置圆环的宽度mPaint.setColor(mRoundProgressColor); //设置进度的颜色RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); //用于定义的圆弧的形状和大小的界限    switch(mStyle) {case STROKE:mPaint.setStyle(Paint.Style.STROKE);canvas.drawArc(oval, 0, 360 * mProgress / mMax, false, mPaint);break;case FILL:mPaint.setStyle(Paint.Style.FILL_AND_STROKE);if (mProgress != 0) {canvas.drawArc(oval, 0, 360 * mProgress/ mMax, true, mPaint);  //根据进度画圆弧}break;}}public synchronized int getMax() {return mMax;}/** * 设置进度的最大值 * @param max */public synchronized void setMax(int max) {if(max < 0){throw new IllegalArgumentException("Max not less than 0");}this.mMax = max;}/** * 获取进度.需要同步 * @return */public synchronized float getProgress() {return mProgress;}/** * 设置进度,此为线程安全控件,由于考虑多线程的问题,需要同步 * 刷新界面调用postInvalidate()能在非UI线程刷新 * @param progress */public synchronized void setProgress(float progress) {if (progress < 0) {throw new IllegalArgumentException("Progress not less than 0");}if (progress > mMax) {progress = mMax;}if (progress <= mMax) {this.mProgress = progress;postInvalidate();if (progress == mMax && mListener != null) {mListener.onFinished(true);} else if (mListener != null) {mListener.onCurrentPercent(mMax, (int)progress);}}}private OnProgressListener mListener;public void setOnProgressLister(OnProgressListener listener) {this.mListener = listener;}public interface OnProgressListener {public void onFinished(boolean result);public void onCurrentPercent(int mTotalTime , int mCurrentTime);}public void setTextSize(float textSize) {this.mTextSize = textSize;}public void setRoundWidth(float roundWidth) {this.mRoundWidth = roundWidth;}}
MainActivity.java

package com.jackie.roundprogressbar;import com.jackie.roundprogressbar.RoundProgressBar.OnProgressListener;import android.app.Activity;import android.os.Bundle;import android.os.Handler;public class MainActivity extends Activity implements OnProgressListener {private RoundProgressBar mRoundProgressBar;private Handler mHandler = new Handler();private int mProgress = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRoundProgressBar = (RoundProgressBar) findViewById(R.id.roundprogressbar);mRoundProgressBar.setOnProgressLister(this);mRoundProgressBar.setTextSize(100);mRoundProgressBar.setRoundWidth(50);mHandler.postDelayed(mRunnable, 0);}private Runnable mRunnable = new Runnable() {@Overridepublic void run() {mRoundProgressBar.setProgress(mProgress);mProgress += 5;mHandler.postDelayed(this, 1000);}};@Overridepublic void onFinished(boolean result) {mHandler.removeCallbacks(mRunnable);}@Overridepublic void onCurrentPercent(int mTotalTime, int mCurrentTime) {}}

0 0