1.自定义属性和属性的使用
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="progress_unreach_color" fomat="color"></attr>
<attr name="progress_unreach_height" fomat="dimension"></attr>
<attr name="progress_reach_color" fomat="color"></attr>
<attr name="progress_reach_height" fomat="dimension"></attr>
<attr name="progress_text_color" fomat="color"></attr>
<attr name="progress_text_size" fomat="dimension"></attr>
<attr name="progress_text_offset" fomat="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>
protected int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
protected int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
2.线形进度条
1.初始化默认值
private static final int DEFAULT_TEXT_SIZE = 10;
private static final int DEFAULT_TEXT_COLOR = 0xFFFC00D1;
private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;
private static final int DEFAULT_HEIGHT_UNREACH = 2;
private static final int DEFAULT_COLOR_REACH = DEFAULT_TEXT_COLOR;
private static final int DEFAULT_HEIGHT_REACH = 2;
private static final int DEFAULT_TEXT_OFFSET = 10;
protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
protected int mTextColor = DEFAULT_TEXT_COLOR;
protected int mUnReachColor = DEFAULT_COLOR_UNREACH;
protected int mUnReachHight = dp2px(DEFAULT_HEIGHT_UNREACH);
protected int mReachColor = DEFAULT_COLOR_REACH;
protected int mReachHeight = dp2px(DEFAULT_HEIGHT_REACH);
protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);
2.获取自定义属性
public HorizontalProgressbarWithProgress(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
obtainStyledAttrs(attrs);
}
private void obtainStyledAttrs(AttributeSet attrs) {
// TODO Auto-generated method stub
TypedArray ta = getContext().obtainStyledAttributes(attrs,R.styleable.HorizontalProgressbarWithProgress)
mTextSize = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_size, mTextSize)
mTextColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_text_color, mTextColor)
mTextOffset = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_offset, mTextSize)
mUnReachColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_color, mUnReachColor)
mUnReachHight = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_height, mUnReachHight)
mReachColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_reach_color, mReachColor)
mReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_reach_height,mReachHeight)
ta.recycle()
mPaint.setTextSize(mTextSize)
}
3.测量
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
int widthVal = MeasureSpec.getSize(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(widthVal, height);
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, mUnReachHight), Math.abs(textHeight));
if(mode == MeasureSpec.AT_MOST){
result = Math.min(result, size);
}
}
return result;
}
4.绘制
protected synchronized void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(getPaddingLeft(), getHeight()/2);
boolean noNeedUnRech = false;
String text = getProgress()+"%";
int textWidth = (int) mPaint.measureText(text);
float radio = getProgress()*1.0f/getMax();
float progressX = radio*mRealWidth;
if(progressX+textWidth>mRealWidth){
progressX = mRealWidth - textWidth;
noNeedUnRech = true;
}
float endX = progressX - mTextOffset/2;
if(endX>0){
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mReachHeight);
canvas.drawLine(0, 0, endX, 0, mPaint);
}
mPaint.setColor(mTextColor);
int y =(int) -(mPaint.descent()+mPaint.ascent()/2);
canvas.drawText(text, progressX, y, mPaint);
if(!noNeedUnRech){
float start = progressX + mTextOffset/2 + textWidth;
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHight);
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
}
}
3.圆形进度条
public class RoundProgressbarWithProgress extends
HorizontalProgressbarWithProgress {
private int mRadius = dp2px(30);
private int mMaxPainWidth;
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) (mUnReachHight * 2.5f);
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.RoundProgressbarWithProgress);
mRadius = ta.getDimensionPixelOffset(
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) {
mMaxPainWidth = Math.max(mReachHeight, mUnReachHight);
int expect = mRadius * 2 + mMaxPainWidth + getPaddingLeft()
+ getPaddingRight();
int width = resolveSize(expect, widthMeasureSpec);
int height = resolveSize(expect, heightMeasureSpec);
int readwidth = Math.min(width, height);
mRadius = (readwidth - getPaddingLeft() - getPaddingRight() - mMaxPainWidth) / 2;
setMeasuredDimension(readwidth, readwidth);
}
@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() + mMaxPainWidth / 2, getPaddingTop()
+ mMaxPainWidth / 2);
mPaint.setStyle(Style.STROKE);
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHight);
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHight);
float sweepAngle = getProgress()*1.0f/getMax()*360;
canvas.drawArc(new RectF(0, 0, mRadius*2, mRadius*2), 0, sweepAngle, false, mPaint);
mPaint.setStyle(Style.FILL);
mPaint.setColor(mTextColor);
canvas.drawText(text, mRadius-textWidth/2, mRadius-textHeight, mPaint);
canvas.restore();
}
}
4.
https://github.com/Amant-huangqi/progressbar