来源:http://hi.baidu.com/xiaofanqing/item/52fb162831284cf850fd87b5
在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的进度条样式。
分享到:
相关推荐
纯Java代码创建ProgressBar,不使用xml布局文件,代码解读http://blog.csdn.net/codehxy/article/details/30744439
Android Circular Music ProgressBar Description This Circular Progress bar is a designed and made for music players that need beautiful music progress bar. Choosed for best of the day at uplabs.com ...
If you're using the Eclipse environment then check out the legacy repository here: android-square-progressbar-legacy. You can find my blog post about the newest version here: halcyon.ch - android-...
主要是分段时progressbar的颜色不一样 Canvas:https://developer.android.com/reference/android/graphics/Canvas.html mProgressbarView.setProgress(30,true); 和 mProgressbarView.setProgress(50); 同一个控件...
赠送jar包:progressbar-0.5.5.jar; 赠送原API文档:progressbar-0.5.5-javadoc.jar; 赠送源代码:progressbar-0.5.5-sources.jar; 赠送Maven依赖信息文件:progressbar-0.5.5.pom; 包含翻译后的API文档:...
Android自定义Progressbar 圆形进度条CircleBarView 教程博客:Android自定义View——从零开始实现圆形进度条 效果展示: 水波浪进度框WaveProgressView 教程博客:Android自定义View——从零开始实现...
Android开发之ProgressBar及其style样式的使用一些相关的代码,由于是用kotlin来实现的,所以可能会有不适应,不过代码大同小异,问题不大
赠送jar包:progressbar-0.5.5.jar; 赠送原API文档:progressbar-0.5.5-javadoc.jar; 赠送源代码:progressbar-0.5.5-sources.jar; 赠送Maven依赖信息文件:progressbar-0.5.5.pom; 包含翻译后的API文档:...
www.mars-droid.com/Android开发视频教程ProgressBar 进度条 代码 源码 mars老师讲课 android 视频源码 (在此特别感谢mars的无私奉献,此代码为跟随视频边学边做的)
Android高手进阶教程之----Android 中自定义属性(attr.xml,TypedArray)的使用! .doc Android高手进阶教程之----Android中万能的BaseAdapter(Spinner,ListView,GridView)的使用!.doc Android高手进阶教程之----通过...
Android自定义控件---继承ProgressBar功能扩展 博客地址:http://blog.csdn.net/u012814441
Android下ProgressBar和旗下两个子控件的使用,具体可参见博客http://www.cnblogs.com/plokmju/p/android_ProgressBar.html
通过一个小例子实现Android之自定义ProgressBar。博客地址:http://blog.csdn.net/bingdianlanxin,有问题欢迎留言!
android progressBar test
Android自定义titlebar中设置progressbar
Android应用源码之ProgressBar 几乎全部的用法
AndroidProgressBar_Android ProgressBar进度条的几乎全部的用法源码集.rar
项目地址:https://github.com/FireZenk/FireZenk-s-ProgressBar 效果图:如何使用:在xml布局文件中创建<com.firezenk.progressbar.FZProgressBar android:id="@ id/myProgressBar" android:layout_width=...
Material Design ProgressBar with consistent appearance on Android 4.0 . Why MaterialProgressBar? Consistent appearance on Android 4.0 . Correct tinting across platforms. Able to remove the intrinsic ...