1. 程式人生 > >android實用技巧

android實用技巧

  眾所周知,android可以通過XML檔案來建立selector,以Drawable物件的形式安裝到元件上,以提供統一的風格設定。但是在某些時候,我們需要通過程式碼的形式來實現相同的功能,例如元件數量非常多,對應不同的圖片,這時候如果還用XML的話就需要建立大量的selector檔案,非常繁瑣。

    例如一個TextView使用瞭如下的selector

<TextView
        android:id="@+id/TextView_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:drawableTop="@drawable/selector_tabwidget_icon"
        android:textAlignment="center"
        />
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
	<!-- Non focused states -->
	<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/contact" />
	<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/contact_sel" />
	<!-- Focused states -->
	<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/contact_sel" />
	<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/contact_sel" />
	<!-- Pressed -->
	<item android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/contact_sel" />
	<item android:state_pressed="true" android:drawable="@drawable/contact_sel" />
</selector>

裡面所引用的圖片資原始檔非常多,如果每個檔案都對應一個XML的檔案的話,就會非常繁瑣,修改起來非常麻煩。

  實際上,所有XML設定能做的事情,android裡同樣可以用編碼的方式來實現,像上面那個XML檔案,就可以就下面的程式碼來實現:

StateListDrawable drawable = new StateListDrawable();
        //Non focused states
        drawable.addState(new int[]{-android.R.attr.state_focused, -android.R.attr.state_selected, -android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact));
        drawable.addState(new int[]{-android.R.attr.state_focused, android.R.attr.state_selected, -android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact_sel));
        //Focused states
        drawable.addState(new int[]{android.R.attr.state_focused,-android.R.attr.state_selected, -android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact_sel));
        drawable.addState(new int[]{android.R.attr.state_focused,android.R.attr.state_selected, -android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact_sel));
        //Pressed
        drawable.addState(new int[]{android.R.attr.state_selected, android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact_sel));
        drawable.addState(new int[]{android.R.attr.state_pressed},
                getResources().getDrawable(R.drawable.contact_sel));
         
        TextView textView = (TextView) findViewById(R.id.TextView_title);
                
        textView.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);


注意裡面的“-”號,當XML的設定是false時,就需要使用資源符號的負值來設定

  1. package lab.sodino.statelist;  
  2. import android.app.Activity;  
  3. import android.content.Context;  
  4. import android.content.res.ColorStateList;  
  5. import android.graphics.drawable.Drawable;  
  6. import android.graphics.drawable.StateListDrawable;  
  7. import android.os.Bundle;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.TextView;  
  11. /** 
  12.  * 對TextView設定ColorStateList使其在Normal、Pressed、Focused、Unable四種狀態下顯示不同的顏色。<br/> 
  13.  * StateListDrawable可直接使用圖片應用在相似場合。 
  14.  */
  15. publicclass ActColorStateList extends Activity implements OnClickListener {  
  16.     private TextView txtShow;  
  17.     publicvoid onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.         txtShow = (TextView) findViewById(R.id.txtShow);  
  21.         txtShow.setText("Sodino\nNormal:0xffffffff\nPressed:0xffffff00\nFocused:0xff0000ff\nUnable:0xffff0000");  
  22.         txtShow.setTextColor(createColorStateList(0xffffffff0xffffff000xff0000ff0xffff0000));  
  23.         txtShow.setOnClickListener(this);  
  24.     }  
  25.     /** 對TextView設定不同狀態時其文字顏色。 */
  26.     private ColorStateList createColorStateList(int normal, int pressed, int focused, int unable) {  
  27.         int[] colors = newint[] { pressed, focused, normal, focused, unable, normal };  
  28.         int[][] states = newint[6][];  
  29.         states[0] = newint[] { android.R.attr.state_pressed, android.R.attr.state_enabled };  
  30.         states[1] = newint[] { android.R.attr.state_enabled, android.R.attr.state_focused };  
  31.         states[2] = newint[] { android.R.attr.state_enabled };  
  32.         states[3] = newint[] { android.R.attr.state_focused };  
  33.         states[4] = newint[] { android.R.attr.state_window_focused };  
  34.         states[5] = newint[] {};  
  35.         ColorStateList colorList = new ColorStateList(states, colors);  
  36.         return colorList;  
  37.     }  
  38.     /** 設定Selector。 */
  39.     publicstatic StateListDrawable newSelector(Context context, int idNormal, int idPressed, int idFocused,  
  40.             int idUnable) {  
  41.         StateListDrawable bg = new StateListDrawable();  
  42.         Drawable normal = idNormal == -1 ? null : context.getResources().getDrawable(idNormal);  
  43.         Drawable pressed = idPressed == -1 ? null : context.getResources().getDrawable(idPressed);  
  44.         Drawable focused = idFocused == -1 ? null : context.getResources().getDrawable(idFocused);  
  45.         Drawable unable = idUnable == -1 ? null : context.getResources().getDrawable(idUnable);  
  46.         // View.PRESSED_ENABLED_STATE_SET
  47.         bg.addState(newint[] { android.R.attr.state_pressed, android.R.attr.state_enabled }, pressed);  
  48.         // View.ENABLED_FOCUSED_STATE_SET
  49.         bg.addState(newint[] { android.R.attr.state_enabled, android.R.attr.state_focused }, focused);  
  50.         // View.ENABLED_STATE_SET
  51.         bg.addState(newint[] { android.R.attr.state_enabled }, normal);  
  52.         // View.FOCUSED_STATE_SET
  53.         bg.addState(newint[] { android.R.attr.state_focused }, focused);  
  54.         // View.WINDOW_FOCUSED_STATE_SET
  55.         bg.addState(newint[] { android.R.attr.state_window_focused }, unable);  
  56.         // View.EMPTY_STATE_SET
  57.         bg.addState(newint[] {}, normal);  
  58.         return bg;  
  59.     }  
  60.     @Override
  61.     publicvoid onClick(View v) {  
  62.         if (v == txtShow) {  
  63.             txtShow.setEnabled(false);  
  64.         }  
  65.     }  
  66. }