导读:在ProgressDialog的源码里可以明显的看到,在STYLE_HORIZONTAL和STYLE_SPINNER分别显示的是不同的XML,这就意味着你的进度条要么是转圈,要么是条形的。
1.简介系统ProgressDialog的主要特征
1.在ProgressDialog的源码里可以明显的看到,在STYLE_HORIZONTAL和STYLE_SPINNER分别显示的是不同的XML,这就意味着你的进度条要么是转圈,要么是条形的。
2.不管是上述的任何情况下,系统对各部分文字显示都已经完全格式化。
2.实际情况
但是实际的应用中,我们或者需要改变文字的位置,或者需要转圈和条形共存,甚至是做出完全颠覆系统进度条的个性进度条,这个时候我们必须去重新设计属于你自己的进度条。(个人一直认为应用中的组件尽量不用系统的,而是重写系统的,这样做出来的应用才是百家争鸣)。
下面就实现我自己的进度条中碰到的几个可能需要注意的地方给大家交待下:
1.在系统ProgressDialog的构造函数
1 | public ProgressDialog(Context |
6 | com.android.internal.R.style.Theme_Dialog_Alert); |
中涉及了一个theme:com.android.internal.R.style.Theme_Dialog_Alert,这是我当时遇到的第一个问题,开始的时候翻遍源码,终于在data/res/values/themes.xml里找到,
1 | <style name= "Theme.Dialog.Alert" > |
2 | <item name= "windowBackground" > |
3 | @android :color/transparent</item> |
4 | <item name= "windowTitleStyle" > |
5 | @android :style/DialogWindowTitle |
7 | <item name= "windowIsFloating" > true </item> |
8 | <item name= "windowContentOverlay" > @null </item> |
但是发现他还关联其他style,继续找下去,结果写到自己的XML里还是错误一大堆,最后仔细看了下,发现不就是个theme吗,这就简单了,有2种方向:1.自己写theme.2.使用系统的theme。我写的时候是
1 | public ProgressDialog1(Context context) { |
2 | this (context, android.R.style.Theme_Panel); |
调用系统的android.R.style.Theme_Panel.注意:找个地方就是你个性释放的开始。2.我要实现的是转圈和条形并存。那么肯定得在布局文件上下手了。找个地方分2块说.第1,布局是XML文件;2,布局是代码生成。您可能会问,这有区别吗?事实上,区别还是蛮大的,不知道你注意到没有如下属性style="?android:attr/progressBarStyleHorizontal"试问,如何代码实现? 先说第1种,XML的话比较简单,因为只需要写2个ProgressBar,然后再在代码里控制visible属性就ok,在此不赘述。第2种,style的实现,这是我碰到的第2个难点 最后我在网上找到1篇文章,关于获取父类私有属性的文章,利用反射机制实现了style的设置。以下工具类是转载网上那位朋友的工具类,大家可以借鉴下!
01 | public class BeanUtils { |
04 | public static void setFieldValue( final Object object, |
05 | final String fieldName, final Object value) { |
06 | Field field = getDeclaredField(object, fieldName); |
08 | throw new IllegalArgumentException( "Could not find field [" |
09 | + fieldName + "] on target [" + object + "]" ); |
10 | makeAccessible(field); |
12 | field.set(object, value); |
13 | } catch (IllegalAccessException e) { |
16 | protected static Field getDeclaredField( final Object object, |
17 | final String fieldName) { |
18 | return getDeclaredField(object.getClass(), fieldName); |
20 | protected static Field getDeclaredField( final Class clazz, |
21 | final String fieldName) { |
22 | for (Class superClass = clazz; superClass != Object. class ; superClass = superClass |
25 | return superClass.getDeclaredField(fieldName); |
26 | } catch (NoSuchFieldException e) { |
31 | protected static void makeAccessible(Field field) { |
32 | if (!Modifier.isPublic(field.getModifiers()) |
33 | || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) { |
34 | field.setAccessible( true ); |
有了上面的工具类,就可以简单的设置那些私有属性 比如:
1 | BeanUtils.setFieldValue(progress_h, "mOnlyIndeterminate" , new Boolean( false )); |
2 | BeanUtils.setFieldValue(progress_h, "mMinHeight" , new Integer( 15 )); |
以上就是我重写进度条的全部心得,希望能对阅读完得朋友有些许帮助!
最后附上我的demo,里面我的调用的布局是代码实现的,当然也有XML的。
demo说明:功能是前30条形,30-70转圈,70-100条形 文字跟着变