`
寻梦者
  • 浏览: 637404 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Android 在Java代码中设置style属性--使用代码创建ProgressBar对象

阅读更多

 

在andriod开发中,很大一部分都要与资源打交道,比如说:图片,布局文件,字符串,样式等等。这给我们想要开发一些公共的组件带来很大的困难,因为公共的组件可能更愿意以jar包的形式出现。但是java的jar包中只允许出现java代码而不能出现资源。

 

当我们想要以jar包的形式提供我们自己开发的公共组件时,我们就需要把以代码的形式创建资源。

 

下面提供一个使用全Java代码的形式创建一个ProgressBar。

 

ProgressBar默认的样式是一个圈圈,我们要想其显示为进度条的样式可以在布局文件中使用如下代码:

 

<ProgressBar android:layout_width="fill_parent"

 

android:layout_height="wrap_content"

 

style="?android:attr/progressBarStyleHorizontal"  />

 

上面的关键代码是红色的部分,这部分的代码就是使得ProgressBar由转圈圈的样式变成进度条的样式。使用这种方式创建的ProgressBar不能包含在jar包中。

 

同样我们也可以使用纯代码的形式创建ProgressBar对象,如下:

 

...

 

ProgressBar progressBar = new ProgressBar(context);

 

LineanerLayout layout = new LinearLayout(context);

 

layout.addView(progressBar, new LayoutParam(LayoutParam.FILL_PARENT, LayoutParam.FILL_PARENT));

 

....

 

这样就使用纯代码的方式创建了一个ProgressBar对象,但是他还只是默认的样式一个不停的转的圈圈。

 

这时我们可能都会想到好像没有设置样式。我们可以把之前的那个样式设进去,但是我们找遍API发现View并没有提供任何给我们设置样式的方法。

 

其实样式就是通过一种方式给一个View或一组View设置一些共同的属性值,所以不可能能使用代码来设置。

 

我们可以看下progressBarStyleHorizontal样式中给View设置了哪些属性,我们找到framework下的res目录下的values/Theme.xml文件,搜索progressBarStyleHorizontal会发现如下行:

 

 <item name="progressBarStyleHorizontal">@android:style/Widget.ProgressBar.Horizontal</item> 

 

该主题对应的Widget样式是Widget.ProgressBar.Horizontal,我们在同样的的目录下打开style.xml文件,搜索该样式,可以找到如下代码:

 

  <style name="Widget.ProgressBar.Horizontal"> 

 

        <item name="android:indeterminateOnly">false</item> 

 

        <item name="android:progressDrawable">@android:drawable/progress_horizontal</item> 

 

        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item> 

 

        <item name="android:minHeight">20dip</item> 

 

        <item name="android:maxHeight">20dip</item> 

 

    </style> 

 

也就是progressBarStyleHorizontal样式实际上就是设置了如上的属性,我们直接在布局文件中把如上的值设进去,代码看起来如下:

 

<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" /> 

 

这时运行我们的程序,发现ProgressBar已从圈圈变成进度条的样式。这时我们可以在代码中把这些属性设成布局文件中的值,纯Java代码看起来应该如下面的那样: 

 

ProgressBar progressBar = new ProgressBar(this); 

 

        progressBar.setIndeterminate(false); 

 

        progressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 

 

        progressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal)); 

 

        progressBar.setMinimumHeight(20); 

 

 

 

        LinearLayout layout = new LinearLayout(this); 

 

        layout.addView(progressBar, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 

 

        setContentView(layout); 

 

这时我们发现ProgressBar确实变成了横条,但并没有显示成进度条的样子,我们仔细对比一下纯Java代码和xml布局文件之间差异,我们发现 android:indeterminateOnly="false"和 progressBar.setIndeterminate(false);并不完全一样布局文件的属性有一个Only结尾但代码中并没有,我们查找Api发现并没有setIndeterminateOnly这样的一个方法。 

 

我们打开ProgressBar的源代码,找到.setIndeterminate(false) 方法,方法的代码如下: 

 

 

 

 

 public synchronized void setIndeterminate(boolean indeterminate) { 

 

        if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { 

 

            mIndeterminate = indeterminate; 

 

 

 

            if (indeterminate) { 

 

                // swap between indeterminate and regular backgrounds 

 

                mCurrentDrawable = mIndeterminateDrawable; 

 

                startAnimation(); 

 

            } else { 

 

                mCurrentDrawable = mProgressDrawable; 

 

                stopAnimation(); 

 

            } 

 

        } 

 

    } 

 

我们这时候可以发现Indeterminate和IndeterminateOnly并不是同一个东西,这时我们应该想的到,只要我们把 IndeterminateOnly的值变成false就可以使ProgressBar变成进度条的样式,我们查找所有的代码,发现并没有提供相应的公开方法来修改该属性的值。 

 

也就是说,我们讨论了那么久发现根本就无法通过纯代码的形式来创建一个进度条样式的ProgressBar. 

 

 

 

 

但是。。。 

 

不就是改变一个类的私有变量的值嘛,Java的封装性其实并没有我想的那么好,我们完全可以通过反射机制来修改一个对象的私有变量的值,由于该文章并不是讨论反射的的文章,所以这里只给出通过反射来修改私有变量值的代码,但并不作详细的说明: 

 

我们创建一个新的类,叫BeanUtils.java 

 

类得内容看其来如下: 

 

 

 

 

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); 

 

        } 

 

    } 

 

 

 

 

该工具提供一个共有的方法:public static void setFieldValue(final Object object, final String fieldName, final Object value)来修改一个对象的私有变量的值: 

 

这时我们的ProgressBar代码看起来应该如下: 

 

   ProgressBar progressBar = new ProgressBar(this); 

 

        BeanUtils.setFieldValue(progressBar, "mIndeterminateOnly", new Boolean(false)); 

 

        progressBar.setIndeterminate(false); 

 

        progressBar.setProgressDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal)); 

 

        progressBar.setIndeterminateDrawable(getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal)); 

 

        progressBar.setMinimumHeight(20); 

 

 

 

 

 

        LinearLayout layout = new LinearLayout(this); 

 

        layout.addView(progressBar, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 

 

        setContentView(layout); 

 

 

 

到此为止我们终于使用纯java代码的方式创建了一个ProgressBar的进度条样式。 

 

 

ProcessBar的使用:

 

public class ProcessActivity extends Activity {
	
	private ProgressBar psb_sec;
	private Button btn_process;
	
	private static final int PSB_MAX = 100;
	
	private static int process;
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        psb_sec = (ProgressBar) findViewById(R.id.psb_sec);
        psb_sec.setMax(100); 
        
        btn_process = (Button) findViewById(R.id.btn_process);
        
        btn_process.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(process < PSB_MAX){
					psb_sec.setProgress(process);
					process += PSB_MAX/10;
					psb_sec.setSecondaryProgress(process);
					return;
				}
				psb_sec.setVisibility(View.INVISIBLE);
				
			}
		});
    }
}
 

 

 

分享到:
评论

相关推荐

    纯Java代码创建ProgressBar,不使用xml

    本示例探讨的是如何使用纯Java代码创建ProgressBar,而不是借助XML布局文件来实现这一功能。 首先,我们需要了解ProgressBar的基本使用。在Android中,ProgressBar有两种类型:水平和旋转(indeterminate)。水平...

    Android应用源码之ProgressBar 几乎全部的用法

    ProgressBar的基本使用非常简单,只需在布局文件中添加一个ProgressBar标签,设置其属性,如id、style、max等。例如: ```xml &lt;ProgressBar android:id="@+id/progressBar" style="?android:attr/...

    android Progressbar

    在本案例中,"android progressBar test"很可能是一个示例项目,用于展示如何在Android应用中使用和测试Progressbar的各种功能。 Progressbar在Android中有两种主要类型:LinearProgressBar和CircularProgressBar...

    Android中使用ProgressBar实现进度条

    本篇文章将深入探讨如何在Android中使用ProgressBar以及自定义其样式。 首先,ProgressBar的基本用法是在XML布局文件中声明它。以下是一个简单的例子: ```xml &lt;ProgressBar android:id="@+id/progressBar" ...

    android progressbar使用系列集合

    在Android开发中,ProgressBar是一个非常常见的组件,用于展示任务的进度或者表示正在执行的操作。本篇文章将深入探讨如何自定义ProgressBar以满足特定的设计需求,尤其是根据系统的风格进行定制,包括改变默认背景...

    Android 动态生成 步骤 ProgressBar

    2. **代码创建ProgressBar**: 在Activity或Fragment的Java/Kotlin代码中,先实例化一个ProgressBar对象。例如: ```java ProgressBar progressBar = new ProgressBar(context); ``` 然后设置其属性,如样式、...

    android中自定义progressbar组件

    总结来说,自定义一个基于逐帧动画的ProgressBar组件,涉及到的主要知识点有:ProgressBar组件的使用、动画资源的创建、XML布局文件的编写以及在Java代码中的动画控制。通过这样的实践,开发者可以更好地理解Android...

    android - progressBar

    在XML布局文件中,你需要定义一个`ProgressBar`,可以设置其样式、最大值、当前值等属性。例如: ```xml &lt;ProgressBar android:id="@+id/progressBar" android:layout_width="wrap_content" android:layout_...

    Android progressBar的简单使用例子

    在Android开发中,ProgressBar是一个非常重要的组件,它用于显示进度状态,可以是确定性的,...这个例子展示了如何在Android应用中创建和控制一个基本的ProgressBar,通过查看源代码,你可以更深入地理解其工作原理。

    使用ProgressBar实现进度条,设置进度条显示风格。以及自定义进度条样式

    在Android开发中,ProgressBar是一个非常常见的组件,用于展示任务的执行进度,比如文件...在ProgressBar-master这个项目中,可能包含了更多关于自定义进度条样式的示例代码,可以参考学习以提升你的Android开发技能。

    Android自定义titlebar中设置progressbar

    通过修改ProgressBar的style属性或者创建自定义样式,可以改变进度条的颜色、大小等外观特性。 在Android Studio的项目中,"Mytest008"可能代表了一个示例工程,其中包含了实现上述步骤的具体代码。如果你在实际...

    android自定义progressBar颜色,圆角

    然后,在Java或Kotlin代码中,我们可以像操作普通Progress Bar一样操作这个自定义的Progress Bar,例如设置进度: ```java ProgressBar customProgressBar = findViewById(R.id.custom_progress_bar); ...

    android-testnotification-progressbar

    你可以通过`NotificationChannel`来控制通知的各种属性,并在`NotificationManager`中创建和发布通知。例如: ```java NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "CHANNEL_NAME", ...

    Android实现进度条(ProgressBar)的功能与用法

    对于水平进度条,可以通过设置`android:max`属性来定义最大值,并通过`android:progress`或在代码中动态设置`setProgress()`来调整当前进度。例如,设置最大值为100,初始进度为50: ```xml &lt;ProgressBar android:...

    Android 控件 ProgressBar进度条源码

    在`AndroidManifest.xml`文件中,你可以为ProgressBar设置属性,比如android:visibility来控制其可见性,或者android:indeterminate来指定是否使用不确定模式。同时,你还可以通过style属性应用自定义的主题。 在`...

    Android 之 ProgressBar用法介绍

    2. 在代码中获取ProgressBar实例并设置进度: ```java ProgressBar progressBar = findViewById(R.id.progressBar); progressBar.setProgress(50); // 设置进度为50% ``` 对于更复杂的定制,可以通过以下方式实现:...

    progressbar控件(Android)

    在Android 2.3版本中,开发者可以使用ProgressBar来为用户创建直观的等待反馈,增强用户体验。本篇文章将深入探讨如何在Android 2.3环境下有效地使用ProgressBar控件。 首先,ProgressBar分为两种主要类型:水平...

    Android:ProgressBar的初步学习

    本项目是一个针对初学者的`ProgressBar`初步学习实例,旨在帮助开发者理解如何在Android应用中集成和使用`ProgressBar`。 `ProgressBar`的基本使用: 1. **XML布局文件中的声明**:在`res/layout`目录下的XML布局...

    android 的progressbar教程

    在Java代码中,可以通过`ProgressBar`对象的`setProgress()`方法来改变进度: ```java progressBar.setProgress(value); progressBar.setMax(maxValue); ``` 5. **AsyncTask与ProgressBar** 当进行耗时操作时...

    IndeterminateProgressBar

    3. **代码中使用**:在Activity或Fragment的Java/Kotlin代码中,找到对应的`ProgressBar`实例并设置可见或隐藏,根据需要启动或停止动画。 ```java ProgressBar progressBar = findViewById(R.id.progress_bar); ...

Global site tag (gtag.js) - Google Analytics