2012年4月2日 星期一

ArrayAdapter的使用

ArrayAdapter是Android當中最簡單的adapter,它可以連結一個字串陣列到一個只有一個TextView元件的List物件當中。語法如下:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, new String[]{"今天", "天氣", "很好"});


android.R.layout.simple_list_item_1.xml是Android SDK所提供的資源檔,放在...\platforms\<android version>\data\res\layout子目錄中。它是一個很好的參考,如果只是需要改動該視圖的長寬、顏色等可以更動這個檔案的內容並以另外的名稱儲存備用。

ArrayAdapter提供其它的建構函式,如果child layout裡面不是只有一個簡單的TextView,我們可以自定layout的型式以及需要輸入的字串陣列。

另外也可以在xml裡面定義字串陣列然後再利用createFromResource()將字串與layout連結起來,範例如下:

ListView listview = (ListView) findViewById(<resource Id>);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                    R.array.week, android.R.layout.simple_list_item_1);

listview.setAdapter(adapter);


需要在\res\values\子目錄下建立一個week.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/values/week.xml -->
<resources>
    <string-array name="week">
        <item >星期日</item>
        <item >星期一</item>
        <item >星期二</item>
        <item >星期三</item>
        <item >星期四</item>
        <item >星期五</item>
        <item >星期六</item>
    </string-array>   
</resources>




若是資料的內容有變更,要記住ListView類別是負責顯示在螢幕上,adapter類別才是負責處理資料的繫結。可以利用ArrayAdapter的add()方法新增資料到adapter尾端或是用insert()新增資料到特定的位置;刪除資料則使用remove()方法。


一旦adapter內的資料有了變更,則adapter和ListView的內容就失去了同步,這是侯需要由adapter發送一個notifyDataSetChanged()方法通知ListView重新同步顯示的內容。

當需要自定Layout,且layout當中不只有一個view時,除了系統預設的建構函式以外,比較多的用法是覆寫getView()函式。

ArrayAdapter是繼承自BaseAdapter,當使用BaseAdapter來建構使用者自定的Layout時需要覆寫getCount(), getItem(Int position), getItemId(int position), 還有 getView(int position, View convertView, ViewGroup parent)那麼多函式。雖然大部分有書或是範例可以照抄但是誰曉得一不小心寫錯些什麼會不會搞死自己,這時候可以利用ArrayAdapter化簡一下工作。
我利用一個小技巧,先依照所需要的child view的數量產生一個物件陣列,通常就是String[],或是Bitmap[]或是將會用到的任何物件陣列。將這個物件陣列送給ArrayAdapter當作建構子參數,則ArrayAdapter會幫我們處理掉getCount(), getItem(Int position), getItemId(int position)這幾個函式,剩下的只需要覆寫getView(int position, View convertView, ViewGroup parent)即可,這也是主要的工作。

範例程式碼:

public class TheFirstClassActivity extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    ListView listview = (ListView) findViewById(R.id.listView1);
    testAdapter adapter = new testAdapter(this,
                   new String[]{"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"});
    listview.setAdapter(adapter);
  }



private static class testAdapter extends ArrayAdapter<Object> {
    // XML Layout, 通常自定Layou就會寫死在類別裡,不再透過引數傳入以免產生誤用
    private static final int mResourceId = R.layout.statisticcell;  //自定的layout
    private LayoutInflater mInflater;


    // 預設圖片id
    private static final int[] imgId = { R.drawable.ic_01,
        R.drawable.ic_02, R.drawable.ic_03 };


    public testAdapter(Context context, Object[] objects) {
      super(context, mResourceId, objects);
      mInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);  
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View view;
      if (convertView == null) {
        view = mInflater.inflate(mResourceId, parent, false);
      } else {
        view = convertView;
      }
      
      /**Layout中的UI在這裡綁定,這裡只有一個TextView以及一個ImageView作為範例 */
      TextView tx;
      ImageView iv;     
      tx = (TextView)view.findViewById(R.id.textHour);
      tx.setText((CharSequence) getItem(position));   //抓取由主程式傳進來的字串陣列內容
      iv = (ImageView)view.findViewById(R.id.imageDay1);
      iv.setImageResource(imgId[0]);
      
      return view;
    }
  }
}


沒有留言:

張貼留言