9dfa6e1d0c98ed2e20b16f6232552f235e8c53ae.svn-base 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package com.hjq.widget;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.RectF;
  8. import android.util.AttributeSet;
  9. import android.util.TypedValue;
  10. import android.view.View;
  11. /**
  12. * desc : 数字进度条
  13. */
  14. public final class NumberProgressBar extends View {
  15. // 文本颜色
  16. private int mTextColor;
  17. // 文字大小
  18. private float mTextSize;
  19. // 最大进度
  20. private int mMaxProgress = 100;
  21. // 当前进度
  22. private int mCurrentProgress = 0;
  23. // 进度栏颜色
  24. private int mReachedBarColor;
  25. // 条未到达区域颜色
  26. private int mUnreachedBarColor;
  27. // 到达区域的高度
  28. private float mReachedBarHeight;
  29. // 未到达区域的高度
  30. private float mUnreachedBarHeight;
  31. // 到达区域的画笔
  32. private final Paint mReachedBarPaint;
  33. // 未触及区域的画笔
  34. private final Paint mUnreachedBarPaint;
  35. // 进度文本的绘制
  36. private final Paint mTextPaint;
  37. // 到达的栏区绘制矩形
  38. private final RectF mReachedBound = new RectF(0, 0, 0, 0);
  39. // 未到达的栏区绘制矩形
  40. private final RectF mUnreachedBound = new RectF(0, 0, 0, 0);
  41. // 进度文本偏移量
  42. private float mTextOffset;
  43. public NumberProgressBar(Context context) {
  44. this(context, null);
  45. }
  46. public NumberProgressBar(Context context, AttributeSet attrs) {
  47. this(context, attrs, 0);
  48. }
  49. public NumberProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
  50. super(context, attrs, defStyleAttr);
  51. final TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.NumberProgressBar, defStyleAttr, 0);
  52. mReachedBarColor = array.getColor(R.styleable.NumberProgressBar_pb_reachedColor, Color.rgb(66, 145, 241));
  53. mUnreachedBarColor = array.getColor(R.styleable.NumberProgressBar_pb_unreachedColor, Color.rgb(204, 204, 204));
  54. mTextColor = array.getColor(R.styleable.NumberProgressBar_pb_textColor, Color.rgb(66, 145, 241));
  55. mTextSize = array.getDimension(R.styleable.NumberProgressBar_pb_textSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics()));
  56. mReachedBarHeight = array.getDimension(R.styleable.NumberProgressBar_pb_reachedHeight, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.5f, getResources().getDisplayMetrics()));
  57. mUnreachedBarHeight = array.getDimension(R.styleable.NumberProgressBar_pb_unreachedHeight, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));
  58. mTextOffset = array.getDimension(R.styleable.NumberProgressBar_pb_textOffset, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics()));
  59. setProgress(array.getInt(R.styleable.NumberProgressBar_pb_progress, 0));
  60. setMax(array.getInt(R.styleable.NumberProgressBar_pb_maxProgress, 100));
  61. array.recycle();
  62. mReachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  63. mReachedBarPaint.setColor(mReachedBarColor);
  64. mUnreachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  65. mUnreachedBarPaint.setColor(mUnreachedBarColor);
  66. mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  67. mTextPaint.setColor(mTextColor);
  68. mTextPaint.setTextSize(mTextSize);
  69. }
  70. @Override
  71. protected int getSuggestedMinimumWidth() {
  72. return (int) mTextSize;
  73. }
  74. @Override
  75. protected int getSuggestedMinimumHeight() {
  76. return Math.max((int) mTextSize, Math.max((int) mReachedBarHeight, (int) mUnreachedBarHeight));
  77. }
  78. @Override
  79. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  80. switch (MeasureSpec.getMode(widthMeasureSpec)) {
  81. case MeasureSpec.AT_MOST:
  82. case MeasureSpec.UNSPECIFIED:
  83. widthMeasureSpec = MeasureSpec.makeMeasureSpec(getSuggestedMinimumWidth()
  84. + getPaddingLeft() + getPaddingRight(), MeasureSpec.EXACTLY);
  85. break;
  86. case MeasureSpec.EXACTLY:
  87. break;
  88. }
  89. switch (MeasureSpec.getMode(heightMeasureSpec)) {
  90. case MeasureSpec.AT_MOST:
  91. case MeasureSpec.UNSPECIFIED:
  92. heightMeasureSpec = MeasureSpec.makeMeasureSpec(getSuggestedMinimumHeight()
  93. + getPaddingTop() + getPaddingBottom(), MeasureSpec.EXACTLY);
  94. break;
  95. case MeasureSpec.EXACTLY:
  96. break;
  97. }
  98. setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
  99. }
  100. @Override
  101. protected void onDraw(Canvas canvas) {
  102. // 要在onDraw()中绘制的文本
  103. String text = (getProgress() * 100 / getMax()) + "%";
  104. // 要绘制的文本的宽度
  105. float textWidth = mTextPaint.measureText(text);
  106. // 文本开始位置
  107. float textStart;
  108. boolean drawReachedBar;
  109. if (getProgress() == 0) {
  110. drawReachedBar = false;
  111. textStart = getPaddingLeft();
  112. } else {
  113. drawReachedBar = true;
  114. mReachedBound.left = getPaddingLeft();
  115. mReachedBound.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f;
  116. mReachedBound.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() - mTextOffset + getPaddingLeft();
  117. mReachedBound.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f;
  118. textStart = (mReachedBound.right + mTextOffset);
  119. }
  120. // 文本结束位置
  121. float textEnd = (int) ((getHeight() / 2.0f) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2.0f));
  122. if ((textStart + textWidth) >= getWidth() - getPaddingRight()) {
  123. textStart = getWidth() - getPaddingRight() - textWidth;
  124. mReachedBound.right = textStart - mTextOffset;
  125. }
  126. float unreachedBarStart = textStart + textWidth + mTextOffset;
  127. // 确定是否需要绘制未到达区域
  128. boolean drawUnreachedBar;
  129. if (unreachedBarStart >= getWidth() - getPaddingRight()) {
  130. drawUnreachedBar = false;
  131. } else {
  132. drawUnreachedBar = true;
  133. mUnreachedBound.left = unreachedBarStart;
  134. mUnreachedBound.right = getWidth() - getPaddingRight();
  135. mUnreachedBound.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f;
  136. mUnreachedBound.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f;
  137. }
  138. if (drawReachedBar) {
  139. canvas.drawRect(mReachedBound, mReachedBarPaint);
  140. }
  141. if (drawUnreachedBar) {
  142. canvas.drawRect(mUnreachedBound, mUnreachedBarPaint);
  143. }
  144. canvas.drawText(text, textStart, textEnd, mTextPaint);
  145. }
  146. public int getProgress() {
  147. return mCurrentProgress;
  148. }
  149. public void setProgress(int progress) {
  150. if (progress <= getMax() && progress >= 0) {
  151. mCurrentProgress = progress;
  152. invalidate();
  153. }
  154. }
  155. public int getMax() {
  156. return mMaxProgress;
  157. }
  158. public void setMax(int maxProgress) {
  159. if (maxProgress > 0) {
  160. mMaxProgress = maxProgress;
  161. invalidate();
  162. }
  163. }
  164. public float getReachedBarHeight() {
  165. return mReachedBarHeight;
  166. }
  167. public void setReachedBarHeight(float height) {
  168. mReachedBarHeight = height;
  169. }
  170. public float getUnreachedBarHeight() {
  171. return mUnreachedBarHeight;
  172. }
  173. public void setUnreachedBarHeight(float height) {
  174. mUnreachedBarHeight = height;
  175. }
  176. public void setProgressTextColor(int textColor) {
  177. mTextColor = textColor;
  178. mTextPaint.setColor(mTextColor);
  179. invalidate();
  180. }
  181. public void setProgressTextSize(float textSize) {
  182. mTextSize = textSize;
  183. mTextPaint.setTextSize(mTextSize);
  184. invalidate();
  185. }
  186. public int getUnreachedBarColor() {
  187. return mUnreachedBarColor;
  188. }
  189. public void setUnreachedBarColor(int barColor) {
  190. mUnreachedBarColor = barColor;
  191. mUnreachedBarPaint.setColor(mUnreachedBarColor);
  192. invalidate();
  193. }
  194. public int getReachedBarColor() {
  195. return mReachedBarColor;
  196. }
  197. public void setReachedBarColor(int progressColor) {
  198. mReachedBarColor = progressColor;
  199. mReachedBarPaint.setColor(mReachedBarColor);
  200. invalidate();
  201. }
  202. }