在andriod開發(fā)中妓雾,很大一部分都要與資源打交道,比如說:圖片垒迂,布局文件械姻,字符串,樣式等等机断。這給我們想要開發(fā)一些公共的組件帶來很大的困難楷拳,因為公共的組件可能更愿意以jar包的形式出現(xiàn)材部。但是java的jar包中只允許出現(xiàn)java代碼而不能出現(xiàn)資源。
當(dāng)我們想要以jar包的形式提供我們自己開發(fā)的公共組件時唯竹,我們就需要把以代碼的形式創(chuàng)建資源乐导。
下面提供一個使用全Java代碼的形式創(chuàng)建一個ProgressBar。
ProgressBar默認(rèn)的樣式是一個圈圈浸颓,我們要想其顯示為進(jìn)度條的樣式可以在布局文件中使用如下代碼:
<ProgressBar android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal" />
上面的關(guān)鍵代碼是紅色的部分物臂,這部分的代碼就是使得ProgressBar由轉(zhuǎn)圈圈的樣式變成進(jìn)度條的樣式。使用這種方式創(chuàng)建的ProgressBar不能包含在jar包中产上。
同樣我們也可以使用純代碼的形式創(chuàng)建ProgressBar對象棵磷,如下:
...
ProgressBar progressBar = new ProgressBar(context);
LineanerLayout layout = new LinearLayout(context);
layout.addView(progressBar, new LayoutParam(LayoutParam.FILL_PARENT, LayoutParam.FILL_PARENT));
....
這樣就使用純代碼的方式創(chuàng)建了一個ProgressBar對象,但是他還只是默認(rèn)的樣式一個不停的轉(zhuǎn)的圈圈晋涣。
這時我們可能都會想到好像沒有設(shè)置樣式仪媒。我們可以把之前的那個樣式設(shè)進(jìn)去骄蝇,但是我們找遍API發(fā)現(xiàn)View并沒有提供任何給我們設(shè)置樣式的方法扛门。
其實樣式就是通過一種方式給一個View或一組View設(shè)置一些共同的屬性值旷余,所以不可能能使用代碼來設(shè)置游岳。
我們可以看下progressBarStyleHorizontal樣式中給View設(shè)置了哪些屬性,我們找到framework下的res目錄下的values/Theme.xml文件兴枯,搜索progressBarStyleHorizontal會發(fā)現(xiàn)如下行:
<item name="progressBarStyleHorizontal">@android:style/Widget.ProgressBar.Horizontal</item>
該主題對應(yīng)的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樣式實際上就是設(shè)置了如上的屬性压昼,我們直接在布局文件中把如上的值設(shè)進(jìn)去,代碼看起來如下:
<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" />
這時運行我們的程序瘤运,發(fā)現(xiàn)ProgressBar已從圈圈變成進(jìn)度條的樣式窍霞。這時我們可以在代碼中把這些屬性設(shè)成布局文件中的值,純Java代碼看起來應(yīng)該如下面的那樣:
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);
這時我們發(fā)現(xiàn)ProgressBar確實變成了橫條拯坟,但并沒有顯示成進(jìn)度條的樣子但金,我們仔細(xì)對比一下純Java代碼和xml布局文件之間差異,我們發(fā)現(xiàn) android:indeterminateOnly="false"和 progressBar.setIndeterminate(false);并不完全一樣布局文件的屬性有一個Only結(jié)尾但代碼中并沒有似谁,我們查找Api發(fā)現(xiàn)并沒有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();
}
}
}
我們這時候可以發(fā)現(xiàn)Indeterminate和IndeterminateOnly并不是同一個東西,這時我們應(yīng)該想的到续搀,只要我們把 IndeterminateOnly的值變成false就可以使ProgressBar變成進(jìn)度條的樣式塞琼,我們查找所有的代碼,發(fā)現(xiàn)并沒有提供相應(yīng)的公開方法來修改該屬性的值禁舷。
也就是說彪杉,我們討論了那么久發(fā)現(xiàn)根本就無法通過純代碼的形式來創(chuàng)建一個進(jìn)度條樣式的ProgressBar.
但是毅往。。派近。
不就是改變一個類的私有變量的值嘛攀唯,Java的封裝性其實并沒有我想的那么好,我們完全可以通過反射機(jī)制來修改一個對象的私有變量的值渴丸,由于該文章并不是討論反射的的文章侯嘀,所以這里只給出通過反射來修改私有變量值的代碼,但并不作詳細(xì)的說明:
我們創(chuàng)建一個新的類谱轨,叫BeanUtils.java
類得內(nèi)容看其來如下:
public class BeanUtils {
private BeanUtils() {
}
/**
* 直接設(shè)置對象屬性值,無視private/protected修飾符,不經(jīng)過setter函數(shù).
*/
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);
}
}
/**
* 循環(huán)向上轉(zhuǎn)型,獲取對象的DeclaredField.
*/
protected static Field getDeclaredField(final Object object, final String fieldName) {
return getDeclaredField(object.getClass(), fieldName);
}
/**
* 循環(huán)向上轉(zhuǎn)型,獲取類的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不在當(dāng)前類定義,繼續(xù)向上轉(zhuǎn)型
}
}
return null;
}
/**
* 強(qiáng)制轉(zhuǎn)換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代碼看起來應(yīng)該如下:
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代碼的方式創(chuàng)建了一個ProgressBar的進(jìn)度條樣式戒幔。
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); } }); }}
分享到:Handler對象的Message應(yīng)用 | android中的守護(hù)線程
2011-05-28 10:02
瀏覽 5553
評論(0)
分類:移動開發(fā)
相關(guān)推薦
Android知識庫 34785 關(guān)注 | 3135 收錄
評論
您還沒有登錄,請您登錄后再發(fā)表評論尋夢者
瀏覽: 426101 次
性別: [圖片上傳中。土童。诗茎。(6)]
來自: 杭州
最近訪客 更多訪客>>
en24414115
formoney
心_晴
furmint
文章分類
全部博客 (290)
javaBase (29)
design pattern (3)
javaWeb (4)
android (214)
IDE (4)
linux (10)
jsp (0)
ext (2)
生活 (1)
社區(qū)版塊
我的資訊 (0)
我的論壇 (0)
我的問答 (0)
存檔分類
2013-02 (1)
2012-11 (7)
2012-10 (5)
更多存檔...
最新評論
luo_ganlin: 別的不多說,點個贊献汗!關(guān)于Android隱式啟動Activity
IWSo: 謝樓主敢订!研究了好久,原來是這樣罢吃!android中如何讓LinearLayout實現(xiàn)點擊時背景圖片切換
fantao005x: 粘帖的不錯android中如何讓listview的內(nèi)容全部顯示出來
learner576539763: Android_gqs 寫道請問博主枢析,Viewstub 可實現(xiàn) ...android中ViewStub使用
goontosoon: 抄的什么啊,狗屁不通對ContentProvider中g(shù)etType(Uri uri)
聲明:ITeye文章版權(quán)屬于作者刃麸,受法律保護(hù)醒叁。沒有作者書面許可不得轉(zhuǎn)載。若作者同意轉(zhuǎn)載泊业,必須以超鏈接形式標(biāo)明文章原始出處和作者把沼。? 2003-2017 ITeye.com. All rights reserved. [ 京ICP證110151號 京公網(wǎng)安備110105010620 ]