本文講實現一個自定義列表的Android程序,程序將實現一個使用自定義的適配器(Adapter)綁定數據,通過contextView.setTag綁定數據有按鈕的ListView。
系統顯示列表(ListView)時,首先會實例化一個適配器,本文將實例化一個自定義的適配器。實現自定義適配器,必須手動映射數據,這時就需要重寫getView()方法,系統在繪製列表的每一行的時候將調用此方法。
ListView在開始繪製的時候,系統自動調用getCount()函數,根據函數返回值得到ListView的長度,然後根據這個長度,調用getView()逐一畫出每一行。
具體使用方法可以參考下面代碼,只需記住Android自定義ListView三步驟:
第一步:準備主佈局文件、組件佈局文件等
第二步:獲取並整理數據
第三部:綁定數據,這裏我們是通過自己編寫Adapter類來完成的
Demo程序:
1.首先新建一個list.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:background="#F1E4F1">
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:orientation="horizontal">
<ImageView android:id="@+id/image" android:layout_width="40px"
android:layout_height="40px" android:layout_margin="5px" />
<TextView android:id="@+id/title" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="26px"
android:layout_marginLeft="20px" android:layout_marginTop="10px"
android:textColor="#666872" />
<Button android:id="@+id/view_btn" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="詳細"
android:layout_marginLeft="90px" />
</LinearLayout>
<TextView android:id="@+id/info" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textColor="#666872"
android:textSize="13px" />
</LinearLayout>
2.新建一個適配器類,MyAdapter.java
private ArrayList<HashMap<String, Object>> data;
private LayoutInflater layoutInflater;
private Context context;
public MyAdapter(Context context, ArrayList<HashMap<String, Object>> data) {
this.context = context;
this.data = data;
this.layoutInflater = LayoutInflater.from(context);
}
public int getCount() {
return data.size();
}
/**
* 獲取某一位置的數據
*/
public Object getItem(int position) {
return data.get(position);
}
/**
* 獲取唯一標識
*/
public long getItemId(int position) {
return position;
}
/**
* android繪製每一列的時候,都會調用這個方法
*/
public View getView(int position, View convertView, ViewGroup parent) {
ZuJian zuJian = null;
if (convertView == null) {
zuJian = new ZuJian();
//
獲取組件佈局
convertView = layoutInflater.inflate(R.layout.list, null);
zuJian.imageView = (ImageView) convertView.findViewById(R.id.image);
zuJian.titleView = (TextView) convertView.findViewById(R.id.title);
zuJian.infoView = (TextView) convertView.findViewById(R.id.info);
zuJian.button = (Button) convertView.findViewById(R.id.view_btn);
//
這裏要注意,是使用的tag來存儲數據的。
convertView.setTag(zuJian);
} else {
zuJian = (ZuJian) convertView.getTag();
}
//
綁定數據、以及事件觸發
zuJian.imageView.setBackgroundResource((Integer) data.get(position)
.get("image"));
zuJian.titleView.setText((String) data.get(position).get("title"));
zuJian.infoView.setText((String) data.get(position).get("info"));
zuJian.button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//按鈕觸發事件,自己添加
}
});
return convertView;
}
}
關於上面LayoutInflater的使用:在實際開發種LayoutInflater這個類還是非常有用的。它的作用類似於 findViewById(),不同點是LayoutInflater是用來找layout下xml佈局文件,並且會實例化!。
getView()的三個參數:position表示將顯示的是第幾行,covertView是從佈局文件中inflate來的佈局。我們用LayoutInflater的方法將定義好的list.xml文件提取成View實例用來顯示。然後將xml文件中的各個組件實例化,這樣便可以將數據對應到各個組件上了。但是按鈕爲了響應點擊事件,需要爲它添加點擊監聽器,這樣就能捕獲點擊事件。
3.新建一個組件類,爲顯示在ListView上的組件
public ImageView imageView;
public TextView titleView;
public TextView infoView;
public Button button;
}
4.最後新建一個類GoodsListActivity.java,繼承自ListActivity
@Override
public void onCreate(Bundle savedInstanceState) {
// 數據格式必須嚴格
ArrayList<HashMap<String, Object>> data = getData();
MyAdapter adapter = new MyAdapter(this, data);
setListAdapter(adapter);
}
private ArrayList<HashMap<String, Object>> getData() {
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String,Object>>();
//根據需求添加一些數據,
for (int i = 0; i <10; i++) {
HashMap<String, Object> tempHashMap = new HashMap<String, Object>();
tempHashMap.put("info", content[6]);
tempHashMap.put("image", R.drawable.icon);
tempHashMap.put("title", "餐飲美食");
arrayList.add(tempHashMap);
}
return arrayList;
}
}
至此一個Android自定義列表的程序就完成了,上面這個自定義ListView的例子運行效果如下:
實際運行過程中會發現自定義ListView的每一行沒有焦點了,這是因爲Button佔有了列表的焦點,只要在佈局文件中將Button設置爲無焦點就OK了。