標籤:
原文網址:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0924/1712.html
下面的代碼應該很多人都熟悉:
| 123456 |
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/numpad_button_bg_selected" android:state_selected="true"></item> <item android:drawable="@drawable/numpad_button_bg_pressed" android:state_pressed="true"></item> <item android:drawable="@drawable/numpad_button_bg_normal"></item></selector> |
這是一個給button使用的背景選擇,這種不同狀態顯示不同背景的xml檔案我們稱為selector。其實selector的本質是一個drawable對象。
如果要用java代碼實現上述的selector該如何?呢?答案是StateListDrawable。
我們先看一個實現StateListDrawable的最簡單例子:
| 1234 |
StateListDrawable drawable = new StateListDrawable();drawable.addState(new int[]{android.R.attr.state_focused}, mFocusedDrawable);drawable.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, mEnabledPressedDrawable);drawable.addState(new int[0], mDefaultDrawable); |
這段代碼中我們添加了三種狀態。
下面我們用更規範的代碼來示範如何在java中使用StateListDrawable,以及她對應的xml寫法:
首先定義一個獲得StateListDrawable對象的方法:
| 123456789101112131415 |
private StateListDrawable addStateDrawable(Context context, int idNormal, int idPressed, int idFocused) { StateListDrawable sd = new StateListDrawable(); Drawable normal = idNormal == -1 ? null : context.getResources().getDrawable(idNormal); Drawable pressed = idPressed == -1 ? null : context.getResources().getDrawable(idPressed); Drawable focus = idFocused == -1 ? null : context.getResources().getDrawable(idFocused); //注意該處的順序,只要有一個狀態與之相配,背景就會被換掉 //所以不要把大範圍放在前面了,如果sd.addState(new[]{},normal)放在第一個的話,就沒有什麼效果了 sd.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_focused}, focus); sd.addState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}, pressed); sd.addState(new int[]{android.R.attr.state_focused}, focus); sd.addState(new int[]{android.R.attr.state_pressed}, pressed); sd.addState(new int[]{android.R.attr.state_enabled}, normal); sd.addState(new int[]{}, normal); return sd;} |
其中,就如注釋中所講的addState的順序相當重要。
使用ddStateDrawable
| 123 |
//……前面對Button的聲明略去okBtn.setBackgroundDrawable(addStateDrawable(this, R.drawable.btn_normal, R.drawable.btn_selected, R.drawable.btn_selected));cancelBtn.setBackgroundDrawable(addStateDrawable(this, R.drawable.btn_normal, R.drawable.btn_selected, R.drawable.btn_selected)); |
xml方式實現:
下面對應的具體執行個體,由於是做背景用,該xml將放於/res/drawable下面(StateList中第一個匹配目前狀態的item會被使用。因此,如果第一個item沒有任何狀態特性的話,那麼它將每次都被使用,這也是為什麼預設的值必須總是在最後)
selector的定義:
| 1234567 |
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/btn_selected"/> <item android:state_focused="true" android:drawable="@drawable/btn_selected"/> <item android:state_enabled="true" android:drawable="@drawable/btn_normal"/> <item android:drawable="@drawable/btn_normal" /></selector> |
使用selector
| 1234567891011 |
<Button android:id="@+id/canel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_cancel" android:layout_margin="10dip" android:layout_weight="1" android:textColor="#ffffffff" android:textSize="15sp" android:background="@drawable/button_drawable" /> |
【轉】java代碼中實現android背景選擇的selector-StateListDrawable的應用