服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android带进度的圆形进度条

Android带进度的圆形进度条

2021-05-26 14:43xiaanming Android

这篇文章主要为大家详细介绍了Android带进度的圆形进度条,实现自定义View,自定义属性,感兴趣的小伙伴们可以参考一下

我们还是用一个小例子来看看自定义view和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧

Android带进度的圆形进度条

从上面可以看出,我们可以自定义圆环的颜色,圆环进度的颜色,是否显示进度的百分比,进度百分比的颜色,以及进度是实心还是空心等等,这样子是不是很多元化很方便呢?接下来我们就来教大家怎么来定义

1.在values下面新建一个attrs.xml,现在里面定义我们的属性,不同的属性对应不同的format,接下来我贴上我在自定义这个进度条所用到的属性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="roundprogressbar"
    <attr name="roundcolor" format="color"/>
    <attr name="roundprogresscolor" format="color"/>
    <attr name="roundwidth" format="dimension"></attr>
    <attr name="textcolor" format="color" /> 
    <attr name="textsize" format="dimension" /> 
    <attr name="max" format="integer"></attr> 
    <attr name="textisdisplayable" format="boolean"></attr>
    <attr name="style">
      <enum name="stroke" value="0"></enum>
      <enum name="fill" value="1"></enum>
    </attr>
  </declare-styleable> 
</resources>

2.自定义view的属性我们算是定义好了,接下来就是怎么获取属性和代码的编写了,我们需要在构造方法中获取我们自己定义的相关属性,我们先调用context.obtainstyledattributes(attrs,r.styleable.roundprogressbar)来获取typedarray,然后从typedarray获取我们定义的属性,例如

?
1
2
3
4
5
6
7
8
roundcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundcolor, color.red);
    roundprogresscolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundprogresscolor, color.green);
    textcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_textcolor, color.green);
    textsize = mtypedarray.getdimension(r.styleable.roundprogressbar_textsize, 15);
    roundwidth = mtypedarray.getdimension(r.styleable.roundprogressbar_roundwidth, 5);
    max = mtypedarray.getinteger(r.styleable.roundprogressbar_max, 100);
    textisdisplayable = mtypedarray.getboolean(r.styleable.roundprogressbar_textisdisplayable, true);
    style = mtypedarray.getint(r.styleable.roundprogressbar_style, 0);

上面的代码中,如roundcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundcolor, color.red); getcolor方法的第一个参数是我们在xml文件中定义的颜色,如果我们没有给我们自定义的view定义颜色,他就会使用第二个参数中的默认值,即color.red

3.为了方便大家理解,我将自定义view的全部代码贴出来,里面的代码我也有详细的注释

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
package com.example.roundprogressbar;
 
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.graphics.typeface;
import android.util.attributeset;
import android.util.log;
import android.view.view;
 
import com.example.circlepregress.r;
 
/**
 * 仿iphone带进度的进度条,线程安全的view,可直接在线程中更新进度
 * @author xiaanming
 *
 */
public class roundprogressbar extends view {
  /**
   * 画笔对象的引用
   */
  private paint paint;
   
  /**
   * 圆环的颜色
   */
  private int roundcolor;
   
  /**
   * 圆环进度的颜色
   */
  private int roundprogresscolor;
   
  /**
   * 中间进度百分比的字符串的颜色
   */
  private int textcolor;
   
  /**
   * 中间进度百分比的字符串的字体
   */
  private float textsize;
   
  /**
   * 圆环的宽度
   */
  private float roundwidth;
   
  /**
   * 最大进度
   */
  private int max;
   
  /**
   * 当前进度
   */
  private int progress;
  /**
   * 是否显示中间的进度
   */
  private boolean textisdisplayable;
   
  /**
   * 进度的风格,实心或者空心
   */
  private int style;
   
  public static final int stroke = 0;
  public static final int fill = 1;
   
  public roundprogressbar(context context) {
    this(context, null);
  }
 
  public roundprogressbar(context context, attributeset attrs) {
    this(context, attrs, 0);
  }
   
  public roundprogressbar(context context, attributeset attrs, int defstyle) {
    super(context, attrs, defstyle);
     
    paint = new paint();
 
     
    typedarray mtypedarray = context.obtainstyledattributes(attrs,
        r.styleable.roundprogressbar);
     
    //获取自定义属性和默认值
    roundcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundcolor, color.red);
    roundprogresscolor = mtypedarray.getcolor(r.styleable.roundprogressbar_roundprogresscolor, color.green);
    textcolor = mtypedarray.getcolor(r.styleable.roundprogressbar_textcolor, color.green);
    textsize = mtypedarray.getdimension(r.styleable.roundprogressbar_textsize, 15);
    roundwidth = mtypedarray.getdimension(r.styleable.roundprogressbar_roundwidth, 5);
    max = mtypedarray.getinteger(r.styleable.roundprogressbar_max, 100);
    textisdisplayable = mtypedarray.getboolean(r.styleable.roundprogressbar_textisdisplayable, true);
    style = mtypedarray.getint(r.styleable.roundprogressbar_style, 0);
     
    mtypedarray.recycle();
  }
   
 
  @override
  protected void ondraw(canvas canvas) {
    super.ondraw(canvas);
     
    /**
     * 画最外层的大圆环
     */
    int centre = getwidth()/2; //获取圆心的x坐标
    int radius = (int) (centre - roundwidth/2); //圆环的半径
    paint.setcolor(roundcolor); //设置圆环的颜色
    paint.setstyle(paint.style.stroke); //设置空心
    paint.setstrokewidth(roundwidth); //设置圆环的宽度
    paint.setantialias(true); //消除锯齿 
    canvas.drawcircle(centre, centre, radius, paint); //画出圆环
     
    log.e("log", centre + "");
     
    /**
     * 画进度百分比
     */
    paint.setstrokewidth(0); 
    paint.setcolor(textcolor);
    paint.settextsize(textsize);
    paint.settypeface(typeface.default_bold); //设置字体
    int percent = (int)(((float)progress / (float)max) * 100); //中间的进度百分比,先转换成float在进行除法运算,不然都为0
    float textwidth = paint.measuretext(percent + "%");  //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
     
    if(textisdisplayable && percent != 0 && style == stroke){
      canvas.drawtext(percent + "%", centre - textwidth / 2, centre + textsize/2, paint); //画出进度百分比
    }
     
     
    /**
     * 画圆弧 ,画圆环的进度
     */
     
    //设置进度是实心还是空心
    paint.setstrokewidth(roundwidth); //设置圆环的宽度
    paint.setcolor(roundprogresscolor); //设置进度的颜色
    rectf oval = new rectf(centre - radius, centre - radius, centre
        + radius, centre + radius); //用于定义的圆弧的形状和大小的界限
     
    switch (style) {
    case stroke:{
      paint.setstyle(paint.style.stroke);
      canvas.drawarc(oval, 0, 360 * progress / max, false, paint); //根据进度画圆弧
      break;
    }
    case fill:{
      paint.setstyle(paint.style.fill_and_stroke);
      if(progress !=0)
        canvas.drawarc(oval, 0, 360 * progress / max, true, paint); //根据进度画圆弧
      break;
    }
    }
     
  }
   
   
  public synchronized int getmax() {
    return max;
  }
 
  /**
   * 设置进度的最大值
   * @param max
   */
  public synchronized void setmax(int max) {
    if(max < 0){
      throw new illegalargumentexception("max not less than 0");
    }
    this.max = max;
  }
 
  /**
   * 获取进度.需要同步
   * @return
   */
  public synchronized int getprogress() {
    return progress;
  }
 
  /**
   * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
   * 刷新界面调用postinvalidate()能在非ui线程刷新
   * @param progress
   */
  public synchronized void setprogress(int progress) {
    if(progress < 0){
      throw new illegalargumentexception("progress not less than 0");
    }
    if(progress > max){
      progress = max;
    }
    if(progress <= max){
      this.progress = progress;
      postinvalidate();
    }
     
  }
   
   
  public int getcriclecolor() {
    return roundcolor;
  }
 
  public void setcriclecolor(int criclecolor) {
    this.roundcolor = criclecolor;
  }
 
  public int getcricleprogresscolor() {
    return roundprogresscolor;
  }
 
  public void setcricleprogresscolor(int cricleprogresscolor) {
    this.roundprogresscolor = cricleprogresscolor;
  }
 
  public int gettextcolor() {
    return textcolor;
  }
 
  public void settextcolor(int textcolor) {
    this.textcolor = textcolor;
  }
 
  public float gettextsize() {
    return textsize;
  }
 
  public void settextsize(float textsize) {
    this.textsize = textsize;
  }
 
  public float getroundwidth() {
    return roundwidth;
  }
 
  public void setroundwidth(float roundwidth) {
    this.roundwidth = roundwidth;
  }
 
 
 
}

4.通过上面几步我们就实现了自定义view,和自定义view的属性,当然使用过程中还是有一点变化,我们必须在界面布局的最顶层加上
 xmlns:android_custom=""这个即命名空间,
红色部分是自定义属性的前缀,什么意思呢?对于android系统控件我们定义其控件属性是用android:xxx="xxxxxxx",而我们自己定义的就用android_custom:xxx = "xxxxxx"
绿色部分则是我们的包的名字
通过上面这两步我们就能自己定义属性了,我贴出自定义view在xml中使用情况

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:android_custom="http://schemas.android.com/apk/res/com.example.circlepregress"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  
  
  <com.example.roundprogressbar.roundprogressbar 
    android:id="@+id/roundprogressbar2"
    android:layout_width="80dip"
    android:layout_height="80dip"
    android:layout_alignleft="@+id/roundprogressbar1"
    android:layout_alignparentbottom="true"
    android:layout_marginbottom="78dp"
      
      
    android_custom:roundcolor="#d1d1d1"
    android_custom:roundprogresscolor="@android:color/black"
    android_custom:textcolor="#9a32cd"
    android_custom:textisdisplayable="false"
    android_custom:roundwidth="10dip"
    android_custom:textsize="18sp"/> 
</relativelayout>

源码下载: 《android带进度的圆形进度条》

以上就是本文的全部内容,希望对大家的学习有所帮助。

延伸 · 阅读

精彩推荐
  • AndroidAndroid界面效果UI开发资料汇总(附资料包)

    Android界面效果UI开发资料汇总(附资料包)

    android ui界面设计,友好的界面会提高用户体验度;同时也增强了android ui界面设计的难度,本文提供了一些常用开发资料(有下载哦)感兴趣的朋友可以了解下...

    Android开发网4672021-01-03
  • AndroidAndroid编程解析XML方法详解(SAX,DOM与PULL)

    Android编程解析XML方法详解(SAX,DOM与PULL)

    这篇文章主要介绍了Android编程解析XML方法,结合实例形式详细分析了Android解析XML文件的常用方法与相关实现技巧,需要的朋友可以参考下...

    liuhe68810052021-05-03
  • Android汇总Android视频录制中常见问题

    汇总Android视频录制中常见问题

    这篇文章主要汇总了Android视频录制中常见问题,帮助大家更好地解决Android视频录制中常见的问题,需要的朋友可以参考下...

    yh_thu5192021-04-28
  • AndroidAndroid程序设计之AIDL实例详解

    Android程序设计之AIDL实例详解

    这篇文章主要介绍了Android程序设计的AIDL,以一个完整实例的形式较为详细的讲述了AIDL的原理及实现方法,需要的朋友可以参考下...

    Android开发网4642021-03-09
  • AndroidAndroid实现固定屏幕显示的方法

    Android实现固定屏幕显示的方法

    这篇文章主要介绍了Android实现固定屏幕显示的方法,实例分析了Android屏幕固定显示所涉及的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    鉴客6192021-03-27
  • AndroidAndroid中AsyncTask详细介绍

    Android中AsyncTask详细介绍

    这篇文章主要介绍了Android中AsyncTask详细介绍,AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合,需要的朋友可以参考下...

    Android开发网7452021-03-11
  • AndroidAndroid实现Service获取当前位置(GPS+基站)的方法

    Android实现Service获取当前位置(GPS+基站)的方法

    这篇文章主要介绍了Android实现Service获取当前位置(GPS+基站)的方法,较为详细的分析了Service基于GPS位置的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    Ruthless8342021-03-31
  • AndroidAndroid CardView+ViewPager实现ViewPager翻页动画的方法

    Android CardView+ViewPager实现ViewPager翻页动画的方法

    本篇文章主要介绍了Android CardView+ViewPager实现ViewPager翻页动画的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Abby代黎明9602022-03-02