MainActivity:
package com.twac.Diy_progressbar;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import com.twac.view.HorizontalProgressBarWithProgress;
import com.twac.view.RoundProgressBarWithProgress;
public class MainActivity extends Activity {
private HorizontalProgressBarWithProgress mProgress;
private RoundProgressBarWithProgress mProgress2;
private static final int MSG_UPDATE = 0x110;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
int progress = mProgress.getProgress();
int progress2 = mProgress2.getProgress();
mProgress.setProgress(++progress);
mProgress2.setProgress(--progress2);
if (progress > 100) {
mHandler.removeMessages(MSG_UPDATE);
}
mHandler.sendEmptyMessageDelayed(MSG_UPDATE, 150);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgress = (HorizontalProgressBarWithProgress) findViewById(R.id.progress01);
mProgress2 = (RoundProgressBarWithProgress) findViewById(R.id.round01);
mHandler.sendEmptyMessage(MSG_UPDATE);
}
}
新建View包,在此包下新建两个类:
1、HorizontalProgressBarWithProgress(继承自ProgressBar)
package com.twac.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;
import com.twac.Diy_progressbar.R;
public class HorizontalProgressBarWithProgress extends ProgressBar {
private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;
private static final int DEFAULT_TEXT_SIZE = 10;// sp
private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
private static final int DEFAULT_REACH_HEIGHT = 2;// dp
private static final int DEFAULT_UNREACH_COLOR = 0XFFD3D6DA;
private static final int DEFAULT_UNREACH_HEIGHT = 2;// dp
private static final int DEFAULT_TEXT_OFFSET = 10;// dp
protected int mTextColor = DEFAULT_TEXT_COLOR;
protected int mTextSize = sptopx(DEFAULT_TEXT_SIZE);
protected int mReachColor = DEFAULT_REACH_COLOR;
protected int mReachHeight = dptopx(DEFAULT_REACH_HEIGHT);
protected int mUnreachColor = DEFAULT_UNREACH_COLOR;
protected int mUnreachHeight = dptopx(DEFAULT_UNREACH_HEIGHT);
protected int mTextOffset = dptopx(DEFAULT_TEXT_OFFSET);
protected Paint mPaint = new Paint();
// 在onMeasure中赋值,在onDraw中应用
private int mRealWidth;
public HorizontalProgressBarWithProgress(Context context) {
this(context, null);
}
public HorizontalProgressBarWithProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HorizontalProgressBarWithProgress(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
obtainStyledAttrs(attrs);
}
// 获取自定义属性
private void obtainStyledAttrs(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs,
R.styleable.HorizontalProgressBarWithProgress);
mTextColor = ta
.getColor(
R.styleable.HorizontalProgressBarWithProgress_progress_text_color,
mTextColor);
mTextSize = (int) ta
.getDimension(
R.styleable.HorizontalProgressBarWithProgress_progress_text_size,
mTextSize);
mReachColor = ta
.getColor(
R.styleable.HorizontalProgressBarWithProgress_progress_reach_color,
mReachColor);
mReachHeight = (int) ta
.getDimension(
R.styleable.HorizontalProgressBarWithProgress_progress_reach_height,
mReachHeight);
mUnreachColor = ta
.getColor(
R.styleable.HorizontalProgressBarWithProgress_progress_unreach_color,
mUnreachColor);
mUnreachHeight = (int) ta
.getDimension(
R.styleable.HorizontalProgressBarWithProgress_progress_unreach_height,
mUnreachHeight);
mTextOffset = (int) ta
.getDimension(
R.styleable.HorizontalProgressBarWithProgress_progress_text_offset,
mTextOffset);
ta.recycle();
mPaint.setTextSize(mTextSize);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
int widthValue = MeasureSpec.getSize(widthMeasureSpec);
int heightValue = measureHeight(heightMeasureSpec);
// 确定View的宽和高
setMeasuredDimension(widthValue, heightValue);
mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
}
private int measureHeight(int heightMeasureSpec) {
int result = 0;
int mode = MeasureSpec.getMode(heightMeasureSpec);
int size = MeasureSpec.getSize(heightMeasureSpec);
if (mode == MeasureSpec.EXACTLY) { // 精确值,用户设定的
result = size;
} else {// 测量值
int textHeight = (int) (mPaint.descent() - mPaint.ascent());
result = getPaddingTop()
+ getPaddingBottom()
+ Math.max(Math.max(mReachHeight, mUnreachHeight),
Math.abs(textHeight));
if (mode == MeasureSpec.AT_MOST) { // 测量值不能超过给定的size值
result = Math.min(size, result);
}
}
return result;
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(getPaddingLeft(), getHeight() / 2);
boolean noNeedUnReachBar = false;
// draw ReachBar
String text = getProgress() + "%";
int textWidth = (int) mPaint.measureText(text);
float radio = getProgress() * 1.0f / getMax();
float progressX = radio * mRealWidth;
if (progressX + textWidth > mRealWidth) {
noNeedUnReachBar = true;
progressX = mRealWidth - textWidth;
}
float endX = progressX - mTextOffset / 2;
if (endX > 0) {
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mReachHeight);
canvas.drawLine(0, 0, endX, 0, mPaint);
}
// draw Text
mPaint.setColor(mTextColor);
int textY = (int) (-(mPaint.descent() + mPaint.ascent()) / 2);
canvas.drawText(text, progressX, textY, mPaint);
// draw unReachBar
if (!noNeedUnReachBar) {
float start = progressX + mTextOffset / 2 + textWidth;
mPaint.setColor(mUnreachColor);
mPaint.setStrokeWidth(mUnreachHeight);
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
}
canvas.restore();
}
// 两个辅助方法
protected int dptopx(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
protected int sptopx(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
}
2、RoundProgressBarWithProgress(继承自HorizontalProgressBarWithProgress)
package com.twac.view;
import com.twac.Diy_progressbar.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
public class RoundProgressBarWithProgress extends
HorizontalProgressBarWithProgress {
private int mRadius = dptopx(30);
private int mMaxPaintWidth;
public RoundProgressBarWithProgress(Context context) {
this(context, null);
}
public RoundProgressBarWithProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundProgressBarWithProgress(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
mReachHeight = (int) (mUnreachHeight * 3f);
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.RoundProgressBarWithProgress);
mRadius = (int) ta.getDimension(
R.styleable.RoundProgressBarWithProgress_radius, mRadius);
ta.recycle();
mPaint.setStyle(Style.STROKE);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeCap(Cap.ROUND);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
mMaxPaintWidth = Math.max(mReachHeight, mUnreachHeight);
int expect = mRadius * 2 + mMaxPaintWidth + getPaddingLeft()
+ getPaddingRight();
int width = resolveSize(expect, widthMeasureSpec);
int height = resolveSize(expect, heightMeasureSpec);
int realWidth = Math.min(width, height);
mRadius = (realWidth - getPaddingLeft() - getPaddingRight() - mMaxPaintWidth) / 2;
setMeasuredDimension(realWidth, realWidth);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
String text = getProgress() + "%";
float textWidth = mPaint.measureText(text);
float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
canvas.save();
// 移动到指定位置
canvas.translate(getPaddingLeft() + mMaxPaintWidth / 2, getPaddingTop()
+ mMaxPaintWidth / 2);
mPaint.setStyle(Style.STROKE);
// draw unReachBar
mPaint.setColor(mUnreachColor);
mPaint.setStrokeWidth(mUnreachHeight);
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
// draw ReachBat
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mReachHeight);
float sweepAngle = getProgress() * 1.0f / getMax() * 360;
canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), 0,
sweepAngle, false, mPaint);
// draw text
mPaint.setColor(mTextColor);
mPaint.setStyle(Style.FILL);
canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight,
mPaint);
canvas.restore();
}
}
布局文件:
<com.twac.view.HorizontalProgressBarWithProgress
android:id="@+id/progress01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:background="#000000"
android:padding="15dp"
android:progress="50"
app:progress_reach_color="#456789" />
<com.twac.view.HorizontalProgressBarWithProgress
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:progress="98"
app:progress_text_color="#000000" />
<com.twac.view.RoundProgressBarWithProgress
android:id="@+id/round01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:progress="40"
app:radius="60dp" >
</com.twac.view.RoundProgressBarWithProgress>
配置文件(values下新建attrs.xml):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="progress_unreach_color" format="color"></attr>
<attr name="progress_unreach_height" format="dimension"></attr>
<attr name="progress_reach_color" format="color"></attr>
<attr name="progress_reach_height" format="dimension"></attr>
<attr name="progress_text_color" format="color"></attr>
<attr name="progress_text_size" format="dimension"></attr>
<attr name="progress_text_offset" format="dimension"></attr>
<declare-styleable name="HorizontalProgressBarWithProgress">
<attr name="progress_unreach_color"></attr>
<attr name="progress_unreach_height"></attr>
<attr name="progress_reach_color"></attr>
<attr name="progress_reach_height"></attr>
<attr name="progress_text_color"></attr>
<attr name="progress_text_size"></attr>
<attr name="progress_text_offset"></attr>
</declare-styleable>
<declare-styleable name="RoundProgressBarWithProgress">
<attr name="radius" format="dimension"></attr>
</declare-styleable>
</resources>