Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2568824
  • 博文数量: 245
  • 博客积分: 4125
  • 博客等级: 上校
  • 技术积分: 3113
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-25 23:56
文章分类

全部博文(245)

文章存档

2015年(2)

2014年(26)

2013年(41)

2012年(40)

2011年(134)

2010年(2)

分类: Android平台

2013-03-28 11:23:59

在上次的「ListView與Adapter之一」中,有說到ArrayAdapter並不適用於自訂(Custom)ListView的場合,所以改用SimpleAdapter。但後來在網路上找到另幾則範例和教學,事實上如果透過改寫(Override)ArrayAdapter中的getView方法也是可以達成自訂ListView的目的。

先看一下getView方法的定義(在介面Adapter中):
getView(int position, View convertView, ViewGroup parent)
Get a View that displays the data at the specified position in the data set.
getView回傳的是一個View物件,回傳的是每一列的要顯示資料的樣子。position指的是引入Adapter的資料數組的位置,convertView指的是轉換過的樣子,parent指的是每個項目視圖上層包含的容器(Container)。有興趣研究可以開啟ArrayAdapter的原始碼來看(事實上它用了另一個方法接在裡面,叫createViewFromResource,看名稱就知這個方法在作什麼的)
除了getView是需要了解的之外,還有一個需要先了解的LayoutInflater類別,Inflater在的,如果你夠宅宅到爆的話,應該知道"充氣娃娃"的英文有一種唸法叫"Inflatable dolls"…所以暫時叫它"充氣"或"膨脹"。
LayoutInflater的用途是:
This class is used to instantiate layout XML file into its corresponding View objects.
所以是可以解析layout的XML檔,然後生成視圖物件,這個過程叫"充氣"。這和findViewById()的功能有點類似,只不過LayoutInflater是解析整個layout的xml,而findViewById()只是解析某個已經設定進來的layout的XML檔中的特定組件。
LayoutInflater不能直接使用,需要透過getLayoutInflater()或getSystemService(String)方法取得目前已掛在正在運作的設備和上下文的實體。(這一段純翻譯官方說明,代表它早就藏在你的系統中)。在Activity中用getLayoutInflater()是最直接、方便、快速的方法。
回到我們的主題中,在getView中使用LayoutInflater的目的,是要把自訂給每一列項目的layout的那個XML檔案解析成一個視圖。這要透過LayoutInflater中的inflate方法(回傳為View),定義如下(註:inflate有多型,這只是其中我們要用的那種):
inflate(int resource, ViewGroup root, boolean attachToRoot)
Inflate a new view hierarchy from the specified xml resource.
以上的知識就可以開始進行getView的改寫,要寫出繼承自ArrayAdapter的MyCustomAdapter,這裡一樣先用內建的simple_list_item_2當每一列的視圖:

点击(此处)折叠或打开

  1. public class MyCustomAdapter extends ArrayAdapter<String> {
  2.  
  3.  public MyCustomAdapter(Context context, int textViewResourceId,
  4.  String[] objects) {
  5.  super(context, textViewResourceId, objects);
  6.  
  7.  }
  8.  
  9.  @Override
  10.  public View getView(int position, View convertView, ViewGroup parent) {
  11.  
  12.  LayoutInflater inflater = getLayoutInflater();
  13.  View row = inflater.inflate(android.R.layout.simple_list_item_2,
  14.  parent, false);
  15.  
  16.  TextView tv1 = (TextView) row.findViewById(android.R.id.text1);
  17.  tv1.setText(mFoods[position]);
  18.  TextView tv2 = (TextView) row.findViewById(android.R.id.text2);
  19.  tv2.setText(mPlaces[position]);
  20.  
  21.  return row;
  22.  }
  23.  }

下面和之前的教學一樣,設定ListActivity用我們寫出來的MyCustomAdapter:

点击(此处)折叠或打开

  1. public void onCreate(Bundle savedInstanceState) {
  2.  super.onCreate(savedInstanceState);
  3.  
  4.  // ListActivity設定adapter
  5.  setListAdapter(new MyCustomAdapter(this,
  6.  android.R.layout.simple_list_item_2, mFoods));
  7.  
  8.  // 啟用按鍵過濾功能,這兩行都會進行過濾
  9.  getListView().setTextFilterEnabled(true);
  10.  }
最後的結果和之前用SimpleAdapter的一樣:
listview2_1
下一步要用自己定義layout的加上圖片在左邊的那一種,MyCustomAdapter的程式碼如下

点击(此处)折叠或打开

  1. public class MyCustomAdapter extends ArrayAdapter<String> {
  2.  
  3.  public MyCustomAdapter(Context context, int textViewResourceId,
  4.  String[] objects) {
  5.  super(context, textViewResourceId, objects);
  6.  
  7.  }
  8.  
  9.  @Override
  10.  public View getView(int position, View convertView, ViewGroup parent) {
  11.  
  12.  LayoutInflater inflater = getLayoutInflater();
  13.  View row = inflater.inflate(R.layout.mylistview2,
  14.  parent, false);
  15.  
  16.  TextView tv1 = (TextView) row.findViewById(R.id.textView1);
  17.  tv1.setText(mFoods[position]);
  18.  TextView tv2 = (TextView) row.findViewById(R.id.textView2);
  19.  tv2.setText(mPlaces[position]);
  20.  TextView tv3 = (TextView) row.findViewById(R.id.textView3);
  21.  tv3.setText(mRatings[position]);
  22.  ImageView iv1=(ImageView) row.findViewById(R.id.imageView1);
  23.  iv1.setImageResource(mPics[position]);
  24.  
  25.  return row;
  26.  }
  27.  }

結果也是和預期的一樣:
listview4

結論:
條條大路通羅馬。對於這種改寫ArrayAdapter的方法,或許在很簡單使用的情況(像我範例的這種),反而比SimpleAdapter簡單得多,是好是壞我就不知道了。不過具備這一些改寫的知識,接下來要研究更複雜的BaseAdapter,就會輕鬆得多了。

阅读(1855) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~