| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- package com.hjq.widget;
- 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.view.View;
- /**
- * desc : 数字进度条
- */
- public final class NumberProgressBar extends View {
- // 文本颜色
- private int mTextColor;
- // 文字大小
- private float mTextSize;
- // 最大进度
- private int mMaxProgress = 100;
- // 当前进度
- private int mCurrentProgress = 0;
- // 进度栏颜色
- private int mReachedBarColor;
- // 条未到达区域颜色
- private int mUnreachedBarColor;
- // 到达区域的高度
- private float mReachedBarHeight;
- // 未到达区域的高度
- private float mUnreachedBarHeight;
- // 到达区域的画笔
- private final Paint mReachedBarPaint;
- // 未触及区域的画笔
- private final Paint mUnreachedBarPaint;
- // 进度文本的绘制
- private final Paint mTextPaint;
- // 到达的栏区绘制矩形
- private final RectF mReachedBound = new RectF(0, 0, 0, 0);
- // 未到达的栏区绘制矩形
- private final RectF mUnreachedBound = new RectF(0, 0, 0, 0);
- // 进度文本偏移量
- private float mTextOffset;
- public NumberProgressBar(Context context) {
- this(context, null);
- }
- public NumberProgressBar(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public NumberProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- final TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.NumberProgressBar, defStyleAttr, 0);
- mReachedBarColor = array.getColor(R.styleable.NumberProgressBar_pb_reachedColor, Color.rgb(66, 145, 241));
- mUnreachedBarColor = array.getColor(R.styleable.NumberProgressBar_pb_unreachedColor, Color.rgb(204, 204, 204));
- mTextColor = array.getColor(R.styleable.NumberProgressBar_pb_textColor, Color.rgb(66, 145, 241));
- mTextSize = array.getDimension(R.styleable.NumberProgressBar_pb_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics()));
- mReachedBarHeight = array.getDimension(R.styleable.NumberProgressBar_pb_reachedHeight, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.5f, getResources().getDisplayMetrics()));
- mUnreachedBarHeight = array.getDimension(R.styleable.NumberProgressBar_pb_unreachedHeight, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));
- mTextOffset = array.getDimension(R.styleable.NumberProgressBar_pb_textOffset, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics()));
- setProgress(array.getInt(R.styleable.NumberProgressBar_pb_progress, 0));
- setMax(array.getInt(R.styleable.NumberProgressBar_pb_maxProgress, 100));
- array.recycle();
- mReachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mReachedBarPaint.setColor(mReachedBarColor);
- mUnreachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mUnreachedBarPaint.setColor(mUnreachedBarColor);
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mTextPaint.setColor(mTextColor);
- mTextPaint.setTextSize(mTextSize);
- }
- @Override
- protected int getSuggestedMinimumWidth() {
- return (int) mTextSize;
- }
- @Override
- protected int getSuggestedMinimumHeight() {
- return Math.max((int) mTextSize, Math.max((int) mReachedBarHeight, (int) mUnreachedBarHeight));
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- switch (MeasureSpec.getMode(widthMeasureSpec)) {
- case MeasureSpec.AT_MOST:
- case MeasureSpec.UNSPECIFIED:
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(getSuggestedMinimumWidth()
- + getPaddingLeft() + getPaddingRight(), MeasureSpec.EXACTLY);
- break;
- case MeasureSpec.EXACTLY:
- break;
- }
- switch (MeasureSpec.getMode(heightMeasureSpec)) {
- case MeasureSpec.AT_MOST:
- case MeasureSpec.UNSPECIFIED:
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(getSuggestedMinimumHeight()
- + getPaddingTop() + getPaddingBottom(), MeasureSpec.EXACTLY);
- break;
- case MeasureSpec.EXACTLY:
- break;
- }
- setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- // 要在onDraw()中绘制的文本
- String text = (getProgress() * 100 / getMax()) + "%";
- // 要绘制的文本的宽度
- float textWidth = mTextPaint.measureText(text);
- // 文本开始位置
- float textStart;
- boolean drawReachedBar;
- if (getProgress() == 0) {
- drawReachedBar = false;
- textStart = getPaddingLeft();
- } else {
- drawReachedBar = true;
- mReachedBound.left = getPaddingLeft();
- mReachedBound.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f;
- mReachedBound.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() - mTextOffset + getPaddingLeft();
- mReachedBound.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f;
- textStart = (mReachedBound.right + mTextOffset);
- }
- // 文本结束位置
- float textEnd = (int) ((getHeight() / 2.0f) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2.0f));
- if ((textStart + textWidth) >= getWidth() - getPaddingRight()) {
- textStart = getWidth() - getPaddingRight() - textWidth;
- mReachedBound.right = textStart - mTextOffset;
- }
- float unreachedBarStart = textStart + textWidth + mTextOffset;
- // 确定是否需要绘制未到达区域
- boolean drawUnreachedBar;
- if (unreachedBarStart >= getWidth() - getPaddingRight()) {
- drawUnreachedBar = false;
- } else {
- drawUnreachedBar = true;
- mUnreachedBound.left = unreachedBarStart;
- mUnreachedBound.right = getWidth() - getPaddingRight();
- mUnreachedBound.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f;
- mUnreachedBound.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f;
- }
- if (drawReachedBar) {
- canvas.drawRect(mReachedBound, mReachedBarPaint);
- }
- if (drawUnreachedBar) {
- canvas.drawRect(mUnreachedBound, mUnreachedBarPaint);
- }
- canvas.drawText(text, textStart, textEnd, mTextPaint);
- }
- public int getProgress() {
- return mCurrentProgress;
- }
- public void setProgress(int progress) {
- if (progress <= getMax() && progress >= 0) {
- mCurrentProgress = progress;
- invalidate();
- }
- }
- public int getMax() {
- return mMaxProgress;
- }
- public void setMax(int maxProgress) {
- if (maxProgress > 0) {
- mMaxProgress = maxProgress;
- invalidate();
- }
- }
- public float getReachedBarHeight() {
- return mReachedBarHeight;
- }
- public void setReachedBarHeight(float height) {
- mReachedBarHeight = height;
- }
- public float getUnreachedBarHeight() {
- return mUnreachedBarHeight;
- }
- public void setUnreachedBarHeight(float height) {
- mUnreachedBarHeight = height;
- }
- public void setProgressTextColor(int textColor) {
- mTextColor = textColor;
- mTextPaint.setColor(mTextColor);
- invalidate();
- }
- public void setProgressTextSize(float textSize) {
- mTextSize = textSize;
- mTextPaint.setTextSize(mTextSize);
- invalidate();
- }
- public int getUnreachedBarColor() {
- return mUnreachedBarColor;
- }
- public void setUnreachedBarColor(int barColor) {
- mUnreachedBarColor = barColor;
- mUnreachedBarPaint.setColor(mUnreachedBarColor);
- invalidate();
- }
- public int getReachedBarColor() {
- return mReachedBarColor;
- }
- public void setReachedBarColor(int progressColor) {
- mReachedBarColor = progressColor;
- mReachedBarPaint.setColor(mReachedBarColor);
- invalidate();
- }
- }
|