前三种实现方式代码出自:

http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/

(源代码下载)http://download.csdn.net/detail/chaoyu168/9616035

近期一直在学习自己定义控件,搜了很多大牛们Blog里分享的小教程。也上GitHub找了一些类似的控件进行学习。发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧。

一、控件介绍:

进度条在App中非经常见,比例如以下载进度、载入图片、打开文章、打开网页等等……都须要这么一个效果让用户知道我们的App正在读取。以构造良好的交互。假设没有这样一个效果的话。用户没法知道东西有没有下载好、图片载入了没有、文章打开了没……会让用户非常不爽。基于这种情景我们的UI设计师们创造了这样一个控件。

二、这篇文章会涉及的知识点:

跟我一样刚入门的Android菜鸟们。我推荐大家先了解一下这些知识点再往下看。

这些知识点我也会推荐一些博客给大家看看。更推荐大家看文档里的解释,当然大牛们能够直接无视……

1、ClipDrawable类:可以对一个drawable类进行剪切操作(即仅仅显示某一部分的区域,还有一部分隐藏),显示多大的区域由level控制(level取值是0~10000)

【博客:http://blog.csdn.net/lonelyroamer/article/details/8244777】、没文档的能够在这看【http://www.apihome.cn/api/android/ClipDrawable.html】

2、自己定义View:guolin大神的深入学习View四部曲

Android
LayoutInflater原理分析,带你一步步深入了解View
——http://blog.csdn.net/guolin_blog/article/details/12921889】

Android视图绘制流程全然解析。带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/16330267】

Android视图状态及重绘流程分析,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/17045157】

Android自己定义View的实现方法,带你一步步深入了解View——http://blog.csdn.net/guolin_blog/article/details/17357967】

3、没看过我写的:Android自己定义控件——老版优酷三级菜单的话,也许须要看看这个:

【RotateAnimation具体解释——http://blog.csdn.net/u012403246/article/details/41415799】

三、Android上的实现方式:

(前三种方法比較简单,第四种方法是GitHub项目的解析,对前三种没兴趣能够直接跳到后边……)

1、效果图:

将进度条的变换过程分解为一帧一帧的图片,将这些一帧一帧的图片连起来构成一个动画。

经常使用于:手机阅读网页、逛社区时,载入图片、文章等不须要清楚知道载入进度,可是须要知道是否进行载入的情景。

这样的方法实现能够通过创建一个animation-list的XML文件,然后给系统API提供的ProgressBar的indeterminateDrawable属性就能够了。(这个属性应该是类似于设置一个动画吧……)

XML:

[html] view
plain
 copy

  1. <?

    xml version="1.0" encoding="utf-8"?>

  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:oneshot="false" >
  4. <item android:duration="150" >
  5. <clip
  6. android:clipOrientation="horizontal"
  7. android:drawable="@drawable/loading_01"
  8. android:gravity="left"/>
  9. </item>
  10. <item android:duration="150" >
  11. <clip
  12. android:clipOrientation="horizontal"
  13. android:drawable="@drawable/loading_02"
  14. android:gravity="left"/>
  15. </item>
  16. <item android:duration="150" >
  17. <clip
  18. android:clipOrientation="horizontal"
  19. android:drawable="@drawable/loading_03"
  20. android:gravity="left"/>
  21. </item>
  22. <item android:duration="150" >
  23. <clip
  24. android:clipOrientation="horizontal"
  25. android:drawable="@drawable/loading_04"
  26. android:gravity="left"/>
  27. </item>
  28. <item android:duration="150" >
  29. <clip
  30. android:clipOrientation="horizontal"
  31. android:drawable="@drawable/loading_05"
  32. android:gravity="left"/>
  33. </item>
  34. <item android:duration="150" >
  35. <clip
  36. android:clipOrientation="horizontal"
  37. android:drawable="@drawable/loading_06"
  38. android:gravity="left"/>
  39. </item>
  40. <item android:duration="150" >
  41. <clip
  42. android:clipOrientation="horizontal"
  43. android:drawable="@drawable/loading_07"
  44. android:gravity="left"/>
  45. </item>
  46. <item android:duration="150" >
  47. <clip
  48. android:clipOrientation="horizontal"
  49. android:drawable="@drawable/loading_08"
  50. android:gravity="left"/>
  51. </item>
  52. <item android:duration="150" >
  53. <clip
  54. android:clipOrientation="horizontal"
  55. android:drawable="@drawable/loading_09"
  56. android:gravity="left"/>
  57. </item>
  58. <item android:duration="150" >
  59. <clip
  60. android:clipOrientation="horizontal"
  61. android:drawable="@drawable/loading_10"
  62. android:gravity="left"/>
  63. </item>
  64. <item android:duration="150" >
  65. <clip
  66. android:clipOrientation="horizontal"
  67. android:drawable="@drawable/loading_11"
  68. android:gravity="left"/>
  69. </item>
  70. <item android:duration="150" >
  71. <clip
  72. android:clipOrientation="horizontal"
  73. android:drawable="@drawable/loading_12"
  74. android:gravity="left"/>
  75. </item>
  76. </animation-list>
[html] view
plain
 copy

  1. <ProgressBar
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content"
  4. android:indeterminateDrawable="@drawable/progressbar1"
  5. />

、效果图:

在上一篇有关自己定义控件的博客里我们使用了一个RotateAnimation类来实现旋转效果 (http://blog.csdn.net/u012403246/article/details/41309161),事实上。我们在这里也能够把一张图片,通过旋转。达到我们要的效果。本质上和上一种方法没多大差别。

我们仅仅须要创建一个rotate的XML。对其属性进行一些简单的设置。然后增加我们要用的图片就能够了。

XML:

[html] view
plain
 copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <rotate xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:pivotX="50%"
  4. android:pivotY="50%"
  5. android:fromDegrees="0"
  6. android:toDegrees="360"
  7. android:interpolator="@android:anim/accelerate_decelerate_interpolator" >
  8. <bitmap
  9. android:antialias="true"
  10. android:filter="true"
  11. android:src="@drawable/loading_360"/>
  12. </rotate>
[html] view
plain
 copy

  1. <ProgressBar
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content"
  4. android:indeterminateDrawable="@drawable/progressbar2"/>

3、效果图:

我们能够弄两张照片。第一张是纯黑色的,然后把这张照片中心挖一个圆出来,圆区域弄成白色,挖出来的圆弄成第二张照片。我们最好还是叠加显示两张照片,刚開始把第二张全然“遮住”。随着载入进度的添加,我们降低遮住的区域把第二张照片慢慢的显示出来。

Android上刚好就有这么一个ClipDrawable类,可以实现剪裁的过程。

我们来看看怎么通过这种方式自己定义一个进度条控件。

代码:

[java] view
plain
 copy

  1. public class MyProgressBar extends FrameLayout{
  2. private boolean running;
  3. private int progress = 0;
  4. private static final int MAX_PROGRESS = 10000;
  5. private ClipDrawable clip;
  6. private Handler handler = new Handler(){
  7. @Override
  8. public void handleMessage(android.os.Message msg) {
  9. if(msg.what == 0x123)
  10. clip.setLevel(progress);
  11. }
  12. };
  13. public MyProgressBar(Context context){
  14. this(context,null,0);
  15. }
  16. public MyProgressBar(Context context,AttributeSet attrs){
  17. this(context,null,0);
  18. }
  19. public MyProgressBar(Context context, AttributeSet attrs, int defStyle) {
  20. super(context, attrs, defStyle);
  21. Init(context);
  22. }
  23. public void Init(Context context){
  24. View view = LayoutInflater.from(context).inflate(R.layout.view, null);
  25. ImageView iv = (ImageView)view.findViewById(R.id.progress_img);
  26. addView(view);
  27. clip = (ClipDrawable)iv.getDrawable();
  28. Thread thread = new Thread(new Runnable() {
  29. @Override
  30. public void run() {
  31. running = true;
  32. while(running){
  33. handler.sendEmptyMessage(0x123);
  34. if(progress == MAX_PROGRESS)
  35. progress = 0;
  36. progress += 100;
  37. try {
  38. Thread.sleep(18);
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. });
  45. thread.start();
  46. }
  47. public void stop(){
  48. progress = 0;
  49. running = false;
  50. }
  51. }

通过代码我们能够看到。逻辑很easy。关键就在于ClipDrawable的setLevel()方法,这个是设置剪裁效果的。

4、效果图:

实现一个View的子类——Progress Wheel类,实现进度条效果。

详细的内容我都写在了凝视上,假设不了解自己定义控件的知识。能够去阅读guolin博客里自己定义View四部曲的解说,讲的挺好的。

代码:

[java] view
plain
 copy

  1. public class ProgressWheel extends View {
  2. //绘制View用到的各种长、宽带大小
  3. private int layout_height = 0;
  4. private int layout_width = 0;
  5. private int fullRadius = 100;
  6. private int circleRadius = 80;
  7. private int barLength = 60;
  8. private int barWidth = 20;
  9. private int rimWidth = 20;
  10. private int textSize = 20;
  11. private float contourSize = 0;
  12. //与页边的间距
  13. private int paddingTop = 5;
  14. private int paddingBottom = 5;
  15. private int paddingLeft = 5;
  16. private int paddingRight = 5;
  17. //View要绘制的颜色
  18. private int barColor = 0xAA000000;
  19. private int contourColor = 0xAA000000;
  20. private int circleColor = 0x00000000;
  21. private int rimColor = 0xAADDDDDD;
  22. private int textColor = 0xFF000000;
  23. //绘制要用的画笔
  24. private Paint barPaint = new Paint();
  25. private Paint circlePaint = new Paint();
  26. private Paint rimPaint = new Paint();
  27. private Paint textPaint = new Paint();
  28. private Paint contourPaint = new Paint();
  29. //绘制要用的矩形
  30. @SuppressWarnings("unused")
  31. private RectF rectBounds = new RectF();
  32. private RectF circleBounds = new RectF();
  33. private RectF circleOuterContour = new RectF();
  34. private RectF circleInnerContour = new RectF();
  35. //动画
  36. //每次绘制要移动的像素数目
  37. private int spinSpeed = 2;
  38. //绘制过程的时间间隔
  39. private int delayMillis = 0;
  40. int progress = 0;
  41. boolean isSpinning = false;
  42. //其它
  43. private String text = "";
  44. private String[] splitText = {};
  45. /**
  46. * ProgressWheel的构造方法
  47. *
  48. * @param context
  49. * @param attrs
  50. */
  51. public ProgressWheel(Context context, AttributeSet attrs) {
  52. super(context, attrs);
  53. parseAttributes(context.obtainStyledAttributes(attrs,
  54. R.styleable.ProgressWheel));
  55. }
  56. //----------------------------------
  57. //初始化一些元素
  58. //----------------------------------
  59. /*
  60. * 调用这种方法时,使View绘制为方形
  61. * From: http://www.jayway.com/2012/12/12/creating-custom-android-views-part-4-measuring-and-how-to-force-a-view-to-be-square/
  62. *
  63. */
  64. @Override
  65. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  66. // 首先我们要调用超类的onMeasure借口
  67. // 原因是我们自己去实现一个方法获得长度、宽度太麻烦了
  68. // 使用超类的的方法很方便并且让复杂的细节可控
  69. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  70. // 在这里我们不能使用getWidth()和getHeight()。

  71. // 由于这两个方法仅仅能在View的布局完毕后才干使用。而一个View的绘制过程是先绘制元素,再绘制Layout
  72. // 所以我们必须使用getMeasuredWidth()和getMeasuredHeight()
  73. int size = 0;
  74. int width = getMeasuredWidth();
  75. int height = getMeasuredHeight();
  76. int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();
  77. int heigthWithoutPadding = height - getPaddingTop() - getPaddingBottom();
  78. // 最后我们用一些简单的逻辑去计算View的大小并调用setMeasuredDimension()去设置View的大小
  79. // 在比較View的长宽前我们不考虑间距,但当我们设置View所须要绘制的面积时。我们要考虑它
  80. // 不考虑间距的View(View内的实际画面)此时就应该是方形的,可是因为间距的存在,终于View所占的面积可能不是方形的
  81. if (widthWithoutPadding > heigthWithoutPadding) {
  82. size = heigthWithoutPadding;
  83. } else {
  84. size = widthWithoutPadding;
  85. }
  86. // 假设你重写了onMeasure()方法。你必须调用setMeasuredDimension()方法
  87. // 这是你设置View大小的唯一途径
  88. // 假设你不调用setMeasuredDimension()方法,父控件会抛出异常。而且程序会崩溃
  89. // 假设我们使用了超类的onMeasure()方法,我们就不是那么须要setMeasuredDimension()方法
  90. // 然而,重写onMeasure()方法是为了改变既有的绘制流程。所以我们必须调用setMeasuredDimension()方法以达到我们的目的
  91. setMeasuredDimension(size + getPaddingLeft() + getPaddingRight(), size + getPaddingTop() + getPaddingBottom());
  92. }
  93. /**
  94. * 使用onSizeChanged方法取代onAttachedToWindow获得View的面积
  95. * 由于这种方法会在測量了MATCH_PARENT和WRAP_CONTENT后立即被调用
  96. * 使用获得的面积设置View
  97. */
  98. @Override
  99. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  100. super.onSizeChanged(w, h, oldw, oldh);
  101. // Share the dimensions
  102. layout_width = w;
  103. layout_height = h;
  104. setupBounds();
  105. setupPaints();
  106. invalidate();
  107. }
  108. /**
  109. * 设置我们想要绘制的progress wheel的颜色
  110. */
  111. private void setupPaints() {
  112. barPaint.setColor(barColor);
  113. barPaint.setAntiAlias(true);
  114. barPaint.setStyle(Style.STROKE);
  115. barPaint.setStrokeWidth(barWidth);
  116. rimPaint.setColor(rimColor);
  117. rimPaint.setAntiAlias(true);
  118. rimPaint.setStyle(Style.STROKE);
  119. rimPaint.setStrokeWidth(rimWidth);
  120. circlePaint.setColor(circleColor);
  121. circlePaint.setAntiAlias(true);
  122. circlePaint.setStyle(Style.FILL);
  123. textPaint.setColor(textColor);
  124. textPaint.setStyle(Style.FILL);
  125. textPaint.setAntiAlias(true);
  126. textPaint.setTextSize(textSize);
  127. contourPaint.setColor(contourColor);
  128. contourPaint.setAntiAlias(true);
  129. contourPaint.setStyle(Style.STROKE);
  130. contourPaint.setStrokeWidth(contourSize);
  131. }
  132. /**
  133. * 设置元素的边界
  134. */
  135. private void setupBounds() {
  136. // 为了保持宽度和长度的一致。我们要获得layout_width和layout_height中较小的一个,从而绘制一个圆
  137. int minValue = Math.min(layout_width, layout_height);
  138. // 计算在绘制过程中在x,y方向的偏移量
  139. int xOffset = layout_width - minValue;
  140. int yOffset = layout_height - minValue;
  141. // 间距加上偏移量
  142. paddingTop = this.getPaddingTop() + (yOffset / 2);
  143. paddingBottom = this.getPaddingBottom() + (yOffset / 2);
  144. paddingLeft = this.getPaddingLeft() + (xOffset / 2);
  145. paddingRight = this.getPaddingRight() + (xOffset / 2);
  146. int width = getWidth(); //this.getLayoutParams().width;
  147. int height = getHeight(); //this.getLayoutParams().height;
  148. rectBounds = new RectF(paddingLeft,
  149. paddingTop,
  150. width - paddingRight,
  151. height - paddingBottom);
  152. circleBounds = new RectF(paddingLeft + barWidth,
  153. paddingTop + barWidth,
  154. width - paddingRight - barWidth,
  155. height - paddingBottom - barWidth);
  156. circleInnerContour = new RectF(circleBounds.left + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.top + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.right - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.bottom - (rimWidth / 2.0f) - (contourSize / 2.0f));
  157. circleOuterContour = new RectF(circleBounds.left - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.top - (rimWidth / 2.0f) - (contourSize / 2.0f), circleBounds.right + (rimWidth / 2.0f) + (contourSize / 2.0f), circleBounds.bottom + (rimWidth / 2.0f) + (contourSize / 2.0f));
  158. fullRadius = (width - paddingRight - barWidth) / 2;
  159. circleRadius = (fullRadius - barWidth) + 1;
  160. }
  161. /**
  162. * 从XML中解析控件的属性
  163. *
  164. * @param a the attributes to parse
  165. */
  166. private void parseAttributes(TypedArray a) {
  167. barWidth = (int) a.getDimension(R.styleable.ProgressWheel_barWidth,
  168. barWidth);
  169. rimWidth = (int) a.getDimension(R.styleable.ProgressWheel_rimWidth,
  170. rimWidth);
  171. spinSpeed = (int) a.getDimension(R.styleable.ProgressWheel_spinSpeed,
  172. spinSpeed);
  173. delayMillis = a.getInteger(R.styleable.ProgressWheel_delayMillis,
  174. delayMillis);
  175. if (delayMillis < 0) {
  176. delayMillis = 0;
  177. }
  178. barColor = a.getColor(R.styleable.ProgressWheel_barColor, barColor);
  179. barLength = (int) a.getDimension(R.styleable.ProgressWheel_barLength,
  180. barLength);
  181. textSize = (int) a.getDimension(R.styleable.ProgressWheel_textSize,
  182. textSize);
  183. textColor = (int) a.getColor(R.styleable.ProgressWheel_textColor,
  184. textColor);
  185. //假设text是空的,就无视它
  186. if (a.hasValue(R.styleable.ProgressWheel_text)) {
  187. setText(a.getString(R.styleable.ProgressWheel_text));
  188. }
  189. rimColor = (int) a.getColor(R.styleable.ProgressWheel_rimColor,
  190. rimColor);
  191. circleColor = (int) a.getColor(R.styleable.ProgressWheel_circleColor,
  192. circleColor);
  193. contourColor = a.getColor(R.styleable.ProgressWheel_contourColor, contourColor);
  194. contourSize = a.getDimension(R.styleable.ProgressWheel_contourSize, contourSize);
  195. // 使用TypedArray获得控件属性时必需要注意:使用结束后必须回收TypedArray的对象
  196. a.recycle();
  197. }
  198. //----------------------------------
  199. //动画
  200. //----------------------------------
  201. protected void onDraw(Canvas canvas) {
  202. super.onDraw(canvas);
  203. //绘制内圆
  204. canvas.drawArc(circleBounds, 360, 360, false, circlePaint);
  205. //绘制边界
  206. canvas.drawArc(circleBounds, 360, 360, false, rimPaint);
  207. canvas.drawArc(circleOuterContour, 360, 360, false, contourPaint);
  208. canvas.drawArc(circleInnerContour, 360, 360, false, contourPaint);
  209. //绘制条纹
  210. if (isSpinning) {
  211. canvas.drawArc(circleBounds, progress - 90, barLength, false,
  212. barPaint);
  213. } else {
  214. canvas.drawArc(circleBounds, -90, progress, false, barPaint);
  215. }
  216. //绘制我们想要设置的文字 (并让它显示在圆水平和垂直方向的中心处)
  217. float textHeight = textPaint.descent() - textPaint.ascent();
  218. float verticalTextOffset = (textHeight / 2) - textPaint.descent();
  219. for (String s : splitText) {
  220. float horizontalTextOffset = textPaint.measureText(s) / 2;
  221. canvas.drawText(s, this.getWidth() / 2 - horizontalTextOffset,
  222. this.getHeight() / 2 + verticalTextOffset, textPaint);
  223. }
  224. if (isSpinning) {
  225. scheduleRedraw();
  226. }
  227. }
  228. private void scheduleRedraw() {
  229. progress += spinSpeed;
  230. if (progress > 360) {
  231. progress = 0;
  232. }
  233. postInvalidateDelayed(delayMillis);
  234. }
  235. /**
  236. *   推断wheel是否在旋转
  237. */
  238. public boolean isSpinning() {
  239. if(isSpinning){
  240. return true;
  241. } else {
  242. return false;
  243. }
  244. }
  245. /**
  246. * 重设进度条的值
  247. */
  248. public void resetCount() {
  249. progress = 0;
  250. setText("0%");
  251. invalidate();
  252. }
  253. /**
  254. * 停止进度条的旋转
  255. */
  256. public void stopSpinning() {
  257. isSpinning = false;
  258. progress = 0;
  259. postInvalidate();
  260. }
  261. /**
  262. * 让进度条开启旋转模式
  263. */
  264. public void spin() {
  265. isSpinning = true;
  266. postInvalidate();
  267. }
  268. /**
  269. * 让进度条每次添加1(最大值为360)
  270. */
  271. public void incrementProgress() {
  272. isSpinning = false;
  273. progress++;
  274. if (progress > 360)
  275. progress = 0;
  276. setText(Math.round(((float) progress / 360) * 100) + "%");
  277. postInvalidate();
  278. }
  279. /**
  280. * 设置进度条为一个确切的数值
  281. */
  282. public void setProgress(int i) {
  283. isSpinning = false;
  284. progress = i;
  285. postInvalidate();
  286. }
  287. //----------------------------------
  288. //get和set方法
  289. //----------------------------------
  290. /**
  291. * 设置progress bar的文字并不须要刷新View
  292. *
  293. * @param text the text to show ('\n' constitutes a new line)
  294. */
  295. public void setText(String text) {
  296. this.text = text;
  297. splitText = this.text.split("\n");
  298. }
  299. public int getCircleRadius() {
  300. return circleRadius;
  301. }
  302. public void setCircleRadius(int circleRadius) {
  303. this.circleRadius = circleRadius;
  304. }
  305. public int getBarLength() {
  306. return barLength;
  307. }
  308. public void setBarLength(int barLength) {
  309. this.barLength = barLength;
  310. }
  311. public int getBarWidth() {
  312. return barWidth;
  313. }
  314. public void setBarWidth(int barWidth) {
  315. this.barWidth = barWidth;
  316. if ( this.barPaint != null ) {
  317. this.barPaint.setStrokeWidth( this.barWidth );
  318. }
  319. }
  320. public int getTextSize() {
  321. return textSize;
  322. }
  323. public void setTextSize(int textSize) {
  324. this.textSize = textSize;
  325. if ( this.textPaint != null ) {
  326. this.textPaint.setTextSize( this.textSize );
  327. }
  328. }
  329. public int getPaddingTop() {
  330. return paddingTop;
  331. }
  332. public void setPaddingTop(int paddingTop) {
  333. this.paddingTop = paddingTop;
  334. }
  335. public int getPaddingBottom() {
  336. return paddingBottom;
  337. }
  338. public void setPaddingBottom(int paddingBottom) {
  339. this.paddingBottom = paddingBottom;
  340. }
  341. public int getPaddingLeft() {
  342. return paddingLeft;
  343. }
  344. public void setPaddingLeft(int paddingLeft) {
  345. this.paddingLeft = paddingLeft;
  346. }
  347. public int getPaddingRight() {
  348. return paddingRight;
  349. }
  350. public void setPaddingRight(int paddingRight) {
  351. this.paddingRight = paddingRight;
  352. }
  353. public int getBarColor() {
  354. return barColor;
  355. }
  356. public void setBarColor(int barColor) {
  357. this.barColor = barColor;
  358. if ( this.barPaint != null ) {
  359. this.barPaint.setColor( this.barColor );
  360. }
  361. }
  362. public int getCircleColor() {
  363. return circleColor;
  364. }
  365. public void setCircleColor(int circleColor) {
  366. this.circleColor = circleColor;
  367. if ( this.circlePaint != null ) {
  368. this.circlePaint.setColor( this.circleColor);
  369. }
  370. }
  371. public int getRimColor() {
  372. return rimColor;
  373. }
  374. public void setRimColor(int rimColor) {
  375. this.rimColor = rimColor;
  376. if ( this.rimPaint != null ) {
  377. this.rimPaint.setColor( this.rimColor );
  378. }
  379. }
  380. public Shader getRimShader() {
  381. return rimPaint.getShader();
  382. }
  383. public void setRimShader(Shader shader) {
  384. this.rimPaint.setShader(shader);
  385. }
  386. public int getTextColor() {
  387. return textColor;
  388. }
  389. public void setTextColor(int textColor) {
  390. this.textColor = textColor;
  391. if ( this.textPaint != null ) {
  392. this.textPaint.setColor( this.textColor );
  393. }
  394. }
  395. public int getSpinSpeed() {
  396. return spinSpeed;
  397. }
  398. public void setSpinSpeed(int spinSpeed) {
  399. this.spinSpeed = spinSpeed;
  400. }
  401. public int getRimWidth() {
  402. return rimWidth;
  403. }
  404. public void setRimWidth(int rimWidth) {
  405. this.rimWidth = rimWidth;
  406. if ( this.rimPaint != null ) {
  407. this.rimPaint.setStrokeWidth( this.rimWidth );
  408. }
  409. }
  410. public int getDelayMillis() {
  411. return delayMillis;
  412. }
  413. public void setDelayMillis(int delayMillis) {
  414. this.delayMillis = delayMillis;
  415. }
  416. public int getContourColor() {
  417. return contourColor;
  418. }
  419. public void setContourColor(int contourColor) {
  420. this.contourColor = contourColor;
  421. if ( contourPaint != null ) {
  422. this.contourPaint.setColor( this.contourColor );
  423. }
  424. }
  425. public float getContourSize() {
  426. return this.contourSize;
  427. }
  428. public void setContourSize(float contourSize) {
  429. this.contourSize = contourSize;
  430. if ( contourPaint != null ) {
  431. this.contourPaint.setStrokeWidth( this.contourSize );
  432. }
  433. }
  434. }

Android自己定义控件:进度条的四种实现方式的更多相关文章

  1. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  2. Android-基本控件和详解四种布局方式

    转自:https://www.cnblogs.com/ludashi/p/4883915.html 一.常用基本控件 1.TextView 看到Android中的TextView, 我不禁的想到了iO ...

  3. Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)

    最近一直在学习自定义控件,搜了许多大牛们Blog里分享的小教程,也上GitHub找了一些类似的控件进行学习.发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧. 一.控件介绍: 进度条在App中非 ...

  4. [转]Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)

    最近一直在学习自定义控件,搜了许多大牛们Blog里分享的小教程,也上GitHub找了一些类似的控件进行学习.发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧. 一.控件介绍: 进度条在App中非 ...

  5. Android自己定义控件系列五:自己定义绚丽水波纹效果

    尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...

  6. android 自己定义控件

    Android自己定义View实现非常easy 继承View,重写构造函数.onDraw.(onMeasure)等函数. 假设自己定义的View须要有自己定义的属性.须要在values下建立attrs ...

  7. Android自己定义控件皮肤

    Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有 ...

  8. android 自己定义控件属性(TypedArray以及attrs解释)

    近期在捣鼓android 自己定义控件属性,学到了TypedArray以及attrs.在这当中看了一篇大神博客Android 深入理解Android中的自己定义属性.我就更加深入学习力一番.我就沿着这 ...

  9. Android 自己定义控件开发入门(二)

    上一次我们讲了一堆实现自己定义控件的理论基础.列举了View类一些能够重写的方法,我们对这些方法的重写是我们继承View类来派生自己定义控件的关键 我通过一个最简单的样例给大家展示了这一个过程,不管是 ...

随机推荐

  1. centos7安装apache 新手入门 图文教程

    操作系统 64位CentOS Linux release 7.2.1511 (Core) 下载apache相关软件 1.apr和apr-util,下载地址: http://apr.apache.org ...

  2. 设置ubuntu 终端显示路径长度

    ~/.bashrc 这个文件记录了用户终端配置. 打开~/.bashrc 这个文件 $: sudo vim ~/.bashrc 找到 将蓝色的w由小写改成大写,可以表示只显示当前目录名称.

  3. 介绍一下开源项目FastAnimationWithPOP

    介绍一下开源项目FastAnimationWithPOP JUL 23RD, 2014 这是一个非常easy的动画框架,基于Facebook的POP库. 使用它你就能够在故事版中以0行代码的代价来加入 ...

  4. Android4.2.2启动动画前播放视频

    首先声明測试平台为瑞芯微的rk3168,Android4.2.2,Android版本号非常重要,由于Android4.0和Android4.2.2的代码有些地方就有差别,并不通用! 首先接到任务不知怎 ...

  5. asp.net MVC 3/4 equivalent to a response.filter

    am in a need to intercept all of the html that will be sent to the browser and replace some tags tha ...

  6. restful api安全验证问题

    没有绝对的安全,这个话题很深, 下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正. 由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以 只要和用户身份有关的 ...

  7. log4j.properties打印日志信息(1)

    log4j.properties log4j.rootLogger=debug,stdout,logfile ### 把日志信息输出到控制台 ### log4j.appender.stdout=org ...

  8. 手机应用:非功能需求 Check List

    服务状态防止并发 网络保持:无线网络,GPRS 网络连接:https,手机助手代理 电量 屏幕保持防止休眠 下载重试机制 定时检查XML 限速下载,线程休眠 下载出错反馈机制 消息广播 状态栏通知 进 ...

  9. Java Net版短网址(ShortUrl)的算法及实现 待续

    算法 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理; 3) ...

  10. HTTP 无状态啊无状态啊

    无状态的根本原因 根本原因是:因为,HTTP协议使用的是Socket套接字TCP连接的,每次监听到的套接字连接是不可能一个个保存起来的.(很消耗资源,假如一个人服务器只保存一个通信连接,一万个岂不是要 ...