使用代码创建ProgressBar

本文介绍如何通过Java代码创建并自定义ProgressBar样式为横条状,解决进度无法刷新的问题,并提供了一个利用反射机制来设置mOnlyIndeterminate字段值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

在自己的项目中,遇到了代码创建ProgressBar,无法更改样式等问题。在交流群里,也有人问过!

今天我就结合我查的资料和大家交流一下。

 

Java代码   
  1. ProgressBar mProgressBar=new ProgressBar(context);   
  2. this.addView(mImageView,0);  
ProgressBar mProgressBar=new ProgressBar(context);
this.addView(mImageView,0);

 

 这样,可以用代码创建一个ProgressBar,可是怎么把的样式改成横条状呢?

在使用XML文件来布局时,会使用style来设置:

 

Java代码
  1. style="?android:attr/progressBarStyleHorizontal"  
style="?android:attr/progressBarStyleHorizontal"

 

 可是我们有代码怎么来设置呢?没ProgressBar.setStyle()方法啊!

查了一下高手写的文章,了理到从源码中可以看出progressBarStyleHorizontal也是一个布局罢了

源码如下:

 

Xml代码   
  1. <ProgressBar android:layout_width="fill_parent"  
  2.   
  3. android:layout_height="wrap_content"  
  4.   
  5. android:indeterminateOnly="false"  
  6.   
  7. android:progressDrawable="@android:drawable/progress_horizontal"  
  8.   
  9. android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"  
  10.   
  11. android:minHeight="20dip"  
  12.   
  13. android:maxHeight="20dip" />  
<ProgressBar android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:indeterminateOnly="false"

android:progressDrawable="@android:drawable/progress_horizontal"

android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"

android:minHeight="20dip"

android:maxHeight="20dip" />

 

 

 

我们可以通过代码来设置:

 

Java代码   
  1. mProgressBar.setIndeterminate(false);   
  2. mProgressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));   
  3. mProgressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal));  
mProgressBar.setIndeterminate(false);
mProgressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));
mProgressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal));

 这样就可以实现ProgressBar的条状布局了!

可这时,我们又会发现ProgressBar的进度,无法刷新

原因是XML文件中的android:indeterminateOnly="false"和 代码中的progressBar.setIndeterminate(false)并不完全一样。布局文件的属性有一个Only结尾但代码中并没有,而查找Api发现并没有setIndeterminateOnly这样的一个方法。

看一下ProgressBar的源码我们会发现ProgressBar中有两个私有变量:mOnlyIndeterminate和mIndeterminate。而程序没有提供设置mOnlyIndeterminate的方法。

这里我们可以使用Java的反射机制来设置。

我们写一个通用的BeanUtils类来进行反射操作:

 

Java代码   
  1. public class BeanUtils {   
  2.     private BeanUtils() {   
  3.   
  4.     }   
  5.   
  6.     /**  
  7.      * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数.  
  8.      */  
  9.     public static void setFieldValue(final Object object, final String fieldName, final Object value) {   
  10.         Field field = getDeclaredField(object, fieldName);   
  11.         if (field == null)   
  12.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");   
  13.         makeAccessible(field);   
  14.         try {   
  15.             field.set(object, value);   
  16.         } catch (IllegalAccessException e) {   
  17.         Log.e("zbkc""", e);   
  18.         }   
  19.     }   
  20.   
  21.     /**  
  22.      * 循环向上转型,获取对象的DeclaredField.  
  23.      */  
  24.     protected static Field getDeclaredField(final Object object, final String fieldName) {   
  25.         return getDeclaredField(object.getClass(), fieldName);   
  26.     }   
  27.   
  28.     /**  
  29.      * 循环向上转型,获取类的DeclaredField.  
  30.      */  
  31.     @SuppressWarnings("unchecked")   
  32.     protected static Field getDeclaredField(final Class clazz, final String fieldName) {   
  33.         for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {   
  34.             try {   
  35.                 return superClass.getDeclaredField(fieldName);   
  36.             } catch (NoSuchFieldException e) {   
  37.                 // Field不在当前类定义,继续向上转型   
  38.             }   
  39.         }   
  40.         return null;   
  41.     }   
  42.   
  43.     /**  
  44.      * 强制转换fileld可访问.  
  45.      */  
  46.     protected static void makeAccessible(Field field) {   
  47.         if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {   
  48.             field.setAccessible(true);   
  49.         }   
  50.     }   
  51. }  
public class BeanUtils {
    private BeanUtils() {

    }

    /**
     * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数.
     */
    public static void setFieldValue(final Object object, final String fieldName, final Object value) {
        Field field = getDeclaredField(object, fieldName);
        if (field == null)
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
        makeAccessible(field);
        try {
            field.set(object, value);
        } catch (IllegalAccessException e) {
        Log.e("zbkc", "", e);
        }
    }

    /**
     * 循环向上转型,获取对象的DeclaredField.
     */
    protected static Field getDeclaredField(final Object object, final String fieldName) {
        return getDeclaredField(object.getClass(), fieldName);
    }

    /**
     * 循环向上转型,获取类的DeclaredField.
     */
    @SuppressWarnings("unchecked")
    protected static Field getDeclaredField(final Class clazz, final String fieldName) {
        for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                // Field不在当前类定义,继续向上转型
            }
        }
        return null;
    }

    /**
     * 强制转换fileld可访问.
     */
    protected static void makeAccessible(Field field) {
        if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
            field.setAccessible(true);
        }
    }
}

 

 

 

然后,我们在创建ProgressBar的地方使用下面的语句设置mOnlyIndeterminate为false

 

Java代码 复制代码  收藏代码
  1. BeanUtils.setFieldValue(mProgressBar, "mOnlyIndeterminate"new Boolean(false));  
BeanUtils.setFieldValue(mProgressBar, "mOnlyIndeterminate", new Boolean(false));

 

 这样就实现了用代码来创建ProgressBar。

下面是我的代码

 

Java代码 复制代码  收藏代码
  1. super(context);   
  2. this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));   
  3. ProgressBar mProgressBar=new ProgressBar(context);   
  4. BeanUtils.setFieldValue(mProgressBar, "mOnlyIndeterminate"new Boolean(false));   
  5. mProgressBar.setIndeterminate(false);   
  6. mProgressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));   
  7. mProgressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal));   
  8. mProgressBar.setLayoutParams(new FrameLayout.LayoutParams(655, Gravity.CENTER_VERTICAL) );   
  9. this.addView(mProgressBar,0);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值