横向的进度条
package com.sdp.panda.myviewapp.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;
import com.sdp.panda.myviewapp.R;
/**
* Created by 80926 on 2016/11/24.
*/
public class MyHorizontalProgressBar extends ProgressBar {
private static final int DEFAULT_TEXT_SIZE = 10;
private static final int DEFAULT_TEXT_COLOR = Color.BLACK;
private static final int DEFAULT_UNREACH_COLOR = 0XFFD3D6DA;
private static final int DEFAULT_UNREACH_HEIGHT = 3;
private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
private static final int DEFAULT_REACH_HEIGHT = 4;
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_UNREACH_COLOR;
protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
protected int mReachColor = DEFAULT_REACH_COLOR;
protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);
private Paint mPaint;
private int mRealWidth;
private TypedArray mTA;
public MyHorizontalProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public MyHorizontalProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyHorizontalProgressBar(Context context) {
this(context, null);
}
private void init(Context context, AttributeSet attrs) {
mPaint = new Paint();
obtainStyledAttrs(attrs);
}
private void obtainStyledAttrs(AttributeSet attrs) {
mTA = getContext().obtainStyledAttributes(attrs, R.styleable.MyHorizontalProgressBar);
mTextSize = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_size, mTextSize);
mTextColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_color, mTextColor);
mTextOffset = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_offset, mTextOffset);
mUnReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_color, mUnReachColor);
mUnReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_height, mUnReachHeight);
mReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_color, mReachColor);
mReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_height, mReachHeight);
mTA.recycle();
mPaint.setTextSize(mTextSize);
}
protected int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
protected int sp2px(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthVal = MeasureSpec.getSize(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(widthVal, height);
mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
}
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) {
result = Math.min(result, size);
}
}
return result;
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.save();
canvas.translate(getPaddingLeft(), getHeight() / 2);
boolean noNeedUnReach = 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;
noNeedUnReach = 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 textHeightCenter = (int) (-(mPaint.descent() + mPaint.ascent()) / 2);
canvas.drawText(text, progressX, textHeightCenter, mPaint);
if (!noNeedUnReach) {
float start = progressX + mTextOffset / 2 + textWidth;
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHeight);
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
}
canvas.restore();
}
}
圆形的进度条
package com.sdp.panda.myviewapp.view;
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.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;
import com.sdp.panda.myviewapp.R;
/**
* Created by 80926 on 2016/11/25.
*/
public class MyRoundProgressBar extends ProgressBar {
private static final int DEFAULT_TEXT_SIZE = 10;
private static final int DEFAULT_TEXT_COLOR = Color.RED;
private static final int DEFAULT_UNREACH_COLOR = Color.BLUE;
private static final int DEFAULT_UNREACH_HEIGHT = 3;
private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
private static final int DEFAULT_REACH_HEIGHT = 4;
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_UNREACH_COLOR;
protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
protected int mReachColor = DEFAULT_REACH_COLOR;
protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);
private Paint mPaint;
private int mRadius = dp2px(30);
private int mMaxPaintWidth;
public MyRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public MyRoundProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyRoundProgressBar(Context context) {
this(context, null);
}
private void init(Context context, AttributeSet attrs) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mReachHeight = (int) (mUnReachHeight * 2.0f);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyRoundProgressBar);
TypedArray mTA = context.obtainStyledAttributes(attrs, R.styleable.MyHorizontalProgressBar);
mRadius = (int) ta.getDimension(R.styleable.MyRoundProgressBar_radius, mRadius);
mTextSize = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_size, mTextSize);
mTextColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_color, mTextColor);
mTextOffset = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_offset, mTextOffset);
mUnReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_color, mUnReachColor);
mUnReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_height, mUnReachHeight);
mReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_color, mReachColor);
mReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_height, mReachHeight);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setDither(true);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setTextSize(mTextSize);
}
@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) {
super.onDraw(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(Paint.Style.STROKE);
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHeight);
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mReachHeight);
float sweepAngle = getProgress() * 1.0f / getMax() * 360;
canvas.drawArc(0,0,mRadius*2,mRadius*2,0,sweepAngle,false,mPaint);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(mTextSize);
mPaint.setColor(mTextColor);
canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight / 2, mPaint);
canvas.restore();
}
protected int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
protected int sp2px(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
}
}
使用的xml文件
res文件夹下的arrts.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="MyHorizontalProgressBar">
<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="MyRoundProgressBar">
<attr name="radius" format="dimension"></attr>
</declare-styleable>
</resources>