当前位置:   article > 正文

Android 自定义滑动进度条_android 游戏自定义进度条带小滑块

android 游戏自定义进度条带小滑块

效果图

开干

自定义进度条继承View。自定义View主要重写OnMeasure()方法和onDraw()方法。onMeasure方法中主要计算控件的大小,onDraw方法绘制内容。

在计算控件大小的时候要注意测量模式。

先看下不同的测量模式下的打印结果

先设置match_parent 测量模式是EXACTLY

设置指定的大小测量模式还是EXACTLY

设置包裹内容测量模式变成了UNSPECIFIED

增加一个可滑动的父控件,测量模式变成了AT_MOST

不管是UNSPECIFIED还是AT_MOST最后MeasureSpec.getSize(widthMeasureSpec);获取的都是父控件的大小。

  1. package com.test;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Paint;
  8. import android.graphics.PaintFlagsDrawFilter;
  9. import android.graphics.RectF;
  10. import android.util.AttributeSet;
  11. import android.util.Log;
  12. import android.view.MotionEvent;
  13. import android.view.View;
  14. import androidx.annotation.Nullable;
  15. public class MyProgress extends View {
  16. /**
  17. * 背景
  18. */
  19. private int mBackgroundColor; //背景颜色
  20. private RectF mBgRectF; //背景矩形
  21. private Paint mBgPaint; //bg画笔
  22. /**
  23. * 进度条
  24. */
  25. private int mProgress=0; //当前进度
  26. private int mProgressColor; //进度颜色
  27. private Paint mProgressPaint; //进度画笔
  28. private RectF mProgressRectF; //进度矩形
  29. /**
  30. * 滑块
  31. */
  32. private Paint mSliderPaint; //滑块画笔
  33. private RectF mSliderRectF; //滑块矩形
  34. /**
  35. * 进度条的宽高
  36. */
  37. private int mWidth;
  38. private int mHeight;
  39. private int mRadius;
  40. /**
  41. * 控件的宽高
  42. */
  43. private int mViewWidth;
  44. private int mViewHeight=0;
  45. /**
  46. * 滑块
  47. */
  48. private Bitmap circleBitmap;
  49. private int mBitmatWidth;
  50. private int mBitmatHeight;
  51. public MyProgress(Context context) {
  52. this(context,null);
  53. }
  54. public MyProgress(Context context, @Nullable AttributeSet attrs) {
  55. this(context, attrs,0);
  56. }
  57. public MyProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  58. super(context, attrs, defStyleAttr);
  59. init(context,attrs);
  60. initPaint();
  61. }
  62. private void init(Context context,AttributeSet attrs) {
  63. TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.MyProgress);
  64. mBackgroundColor=ta.getColor(R.styleable.MyProgress_myProgressBgColor,context.getResources().getColor(R.color.colorLine));
  65. mProgressColor=ta.getColor(R.styleable.MyProgress_myProgressColor,context.getResources().getColor(R.color.text));
  66. mProgress=ta.getColor(R.styleable.MyProgress_myProgress,0);
  67. mHeight=ta.getDimensionPixelSize(R.styleable.MyProgress_myProgressHeight,10);
  68. circleBitmap= BitmapFactory.decodeResource(getResources(),ta.getResourceId(R.styleable.MyProgress_myProgressImg,R.mipmap.img_test));
  69. mRadius=ta.getDimensionPixelSize(R.styleable.MyProgress_myProgressRadius,10);
  70. ta.recycle();
  71. mBitmatWidth = circleBitmap.getWidth();
  72. mBitmatHeight = circleBitmap.getHeight();
  73. }
  74. private void initPaint() {
  75. mBgPaint = new Paint();
  76. mBgPaint.setAntiAlias(true);
  77. mBgPaint.setColor(mBackgroundColor);
  78. mBgPaint.setStyle(Paint.Style.FILL);
  79. mBgPaint.setStrokeCap(Paint.Cap.ROUND);
  80. mSliderPaint = new Paint();
  81. mSliderPaint.setAntiAlias(true);
  82. mSliderPaint.setColor(mProgressColor);
  83. mSliderPaint.setStyle(Paint.Style.FILL);
  84. mSliderPaint.setStrokeCap(Paint.Cap.ROUND);
  85. mProgressPaint = new Paint();
  86. mProgressPaint.setAntiAlias(true);
  87. mProgressPaint.setFilterBitmap(true);//paint抗锯齿(true);
  88. mProgressPaint.setColor(mProgressColor);
  89. mProgressPaint.setStyle(Paint.Style.FILL);
  90. mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
  91. }
  92. @Override
  93. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  94. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  95. //宽的测量模式
  96. int widthMode=MeasureSpec.getMode(widthMeasureSpec);
  97. //Extracts the size from the supplied measure specification.
  98. //翻译 从提供的度量规范中提取大小 获取指定大小没有就获取父控件的大小
  99. int width=MeasureSpec.getSize(widthMeasureSpec);
  100. int heightMode=MeasureSpec.getMode(heightMeasureSpec);
  101. int height=MeasureSpec.getSize(heightMeasureSpec);
  102. //EXACTLY == 1073741824
  103. //UNSPECIFIED == -2147483648
  104. //AT_MOST == 0
  105. Log.e("test","widthMode=="+widthMode);
  106. Log.e("test","width=="+width);
  107. int widthSize;
  108. int heightSize;
  109. if(widthMode==MeasureSpec.EXACTLY){ //已经确定具体大小 如设置match_parent或者设置具体值
  110. widthSize=width;
  111. }else{ //没有确定大小
  112. //为了方便随便定义一个大小
  113. widthSize=500;
  114. }
  115. if (heightMode == MeasureSpec.EXACTLY) {
  116. heightSize = height;
  117. } else {
  118. heightSize = mBitmatHeight; //没有定义高度就取滑块的高度
  119. }
  120. mViewWidth = widthSize;
  121. mViewHeight = heightSize;
  122. //进度条的宽度=控件宽-滑块宽
  123. mWidth = mViewWidth - mBitmatWidth;
  124. setMeasuredDimension(mViewWidth, mViewHeight);
  125. }
  126. private PaintFlagsDrawFilter mPaintFilter;
  127. private int left,top,right,bottom;
  128. @Override
  129. protected void onDraw(Canvas canvas) {
  130. super.onDraw(canvas);
  131. if (mPaintFilter == null) {
  132. mPaintFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
  133. //初始化背景的起始位置
  134. left=mBitmatWidth / 2;
  135. top=(mBitmatHeight - mHeight) / 2;
  136. right=(left + mWidth);
  137. bottom=(mBitmatHeight + mHeight)/2;
  138. }
  139. canvas.setDrawFilter(mPaintFilter);//canvas抗锯齿
  140. //画背景
  141. if (mBgRectF == null) {
  142. mBgRectF = new RectF(left, top, right, bottom);
  143. }
  144. canvas.drawRoundRect(mBgRectF, mRadius, mRadius, mBgPaint);
  145. //step2:画进度
  146. //起始位置和背景的起始位置一样
  147. if (mProgress == 0) {
  148. mProgressRectF = new RectF(left, top, left, top);
  149. } else {
  150. mProgressRectF = new RectF(left, top, (mViewWidth-mBitmatWidth)* mProgress/ 100+left, bottom);
  151. }
  152. canvas.drawRoundRect(mProgressRectF, mRadius, mRadius, mProgressPaint);
  153. //step3:画滑块
  154. // canvas.translate(0, -(circleBitmap.getHeight() - mHeight) / 2);
  155. if (mProgress == 0) {
  156. mSliderRectF = new RectF(0, 0, mBitmatWidth, mBitmatHeight);
  157. } else {
  158. mSliderRectF = new RectF((mViewWidth-mBitmatWidth)*mProgress/100 , 0, (mViewWidth-mBitmatWidth)* mProgress/ 100 + mBitmatWidth, mBitmatHeight);
  159. }
  160. canvas.drawBitmap(circleBitmap, null, mSliderRectF, mSliderPaint);
  161. }
  162. @Override
  163. public boolean onTouchEvent(MotionEvent event) {
  164. if (event.getAction() == MotionEvent.ACTION_DOWN) {
  165. //按下,获取点击的位置
  166. float x = event.getX();
  167. float y = event.getY();
  168. if (x-mBitmatWidth/2-mWidth >= 0) {
  169. mProgress = 100;
  170. } else if (x <= mBitmatWidth / 2) {
  171. mProgress = 0;
  172. } else {
  173. mProgress = (int) ((x-mBitmatHeight/2) * 100 / mWidth);
  174. }
  175. } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
  176. //移动,获取移动后的位置
  177. float x = event.getX();
  178. float y = event.getY();
  179. //触摸在这个控件范围内
  180. if ((y > 0 && y < mBitmatHeight) && ((x>= mBitmatWidth/2) || (x<=mWidth + mBitmatWidth/2))) {
  181. if (x-mBitmatWidth/2-mWidth >= 0) {
  182. mProgress = 100;
  183. } else if (x <= mBitmatWidth / 2) {
  184. mProgress = 0;
  185. } else {
  186. mProgress = (int) ((x-mBitmatHeight/2) * 100 / mWidth);
  187. }
  188. }
  189. }
  190. invalidate();
  191. return true;
  192. }
  193. }

 添加自定义属性

  1. <declare-styleable name="MyProgress">
  2. <!--背景颜色-->
  3. <attr name="myProgressBgColor" format="color|reference"/>
  4. <!--进度条颜色-->
  5. <attr name="myProgressColor" format="color|reference"/>
  6. <!--进度-->
  7. <attr name="myProgress" format="integer"/>
  8. <!--进度条的高-->
  9. <attr name="myProgressHeight" format="dimension|reference"/>
  10. <!--中间的图片-->
  11. <attr name="myProgressImg" format="reference"/>
  12. <!--圆角-->
  13. <attr name="myProgressRadius" format="dimension"/>
  14. </declare-styleable>

最后使用

  1. <com.test.MyProgress
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent" />

 最后博客写的少,没写好。不喜勿喷。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/314826
推荐阅读
相关标签
  

闽ICP备14008679号