本文轉自:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html
如欲獲得更多更好的信息,請訪問原文地址,這裏僅作記載
有按鈕的ListView
但是有時候,列表不光會用來做顯示用,我們同樣可以在在上面添加按鈕。添加按鈕首先要寫一個有按鈕的xml文件,然後自然會想到用上面的方法定義一個適配器,然後將數據映射到佈局文件上。但是事實並非這樣,因爲按鈕是無法映射的,即使你成功的用佈局文件顯示出了按鈕也無法添加按鈕的響應,這時就要研究一下ListView是如何現實的了,而且必須要重寫一個類繼承BaseAdapter。下面的示例將顯示一個按鈕和一個圖片,兩行字如果單擊按鈕將刪除此按鈕的所在行。並告訴你ListView究竟是如何工作的。效果如下:
vlist2.xml
01 |
<? xml version = "1.0" encoding = "utf-8" ?> |
02 |
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 |
android:orientation = "horizontal" |
04 |
android:layout_width = "fill_parent" |
05 |
android:layout_height = "fill_parent" > |
06 |
|
07 |
|
08 |
< ImageView android:id = "@+id/img" |
09 |
android:layout_width = "wrap_content" |
10 |
android:layout_height = "wrap_content" |
11 |
android:layout_margin = "5px" /> |
12 |
|
13 |
< LinearLayout android:orientation = "vertical" |
14 |
android:layout_width = "wrap_content" |
15 |
android:layout_height = "wrap_content" > |
16 |
|
17 |
< TextView android:id = "@+id/title" |
18 |
android:layout_width = "wrap_content" |
19 |
android:layout_height = "wrap_content" |
20 |
android:textColor = "#FFFFFFFF" |
21 |
android:textSize = "22px" /> |
22 |
< TextView android:id = "@+id/info" |
23 |
android:layout_width = "wrap_content" |
24 |
android:layout_height = "wrap_content" |
25 |
android:textColor = "#FFFFFFFF" |
26 |
android:textSize = "13px" /> |
27 |
|
28 |
</ LinearLayout > |
29 |
|
30 |
|
31 |
< Button android:id = "@+id/view_btn" |
32 |
android:layout_width = "wrap_content" |
33 |
android:layout_height = "wrap_content" |
34 |
android:text = "@string/s_view_btn" |
35 |
android:layout_gravity = "bottom|right" /> |
36 |
</ LinearLayout > |
程序代碼:
001 |
/** |
002 |
*
@author allin |
003 |
* |
004 |
*/ |
005 |
public class MyListView4 extends ListActivity
{ |
006 |
|
007 |
|
008 |
private List<Map<String,
Object>> mData; |
009 |
|
010 |
@Override |
011 |
public void onCreate(Bundle
savedInstanceState) { |
012 |
super .onCreate(savedInstanceState); |
013 |
mData
= getData(); |
014 |
MyAdapter
adapter = new MyAdapter( this ); |
015 |
setListAdapter(adapter); |
016 |
} |
017 |
|
018 |
private List<Map<String,
Object>> getData() { |
019 |
List<Map<String,
Object>> list = new ArrayList<Map<String,
Object>>(); |
020 |
|
021 |
Map<String,
Object> map = new HashMap<String,
Object>(); |
022 |
map.put( "title" , "G1" ); |
023 |
map.put( "info" , "google
1" ); |
024 |
map.put( "img" ,
R.drawable.i1); |
025 |
list.add(map); |
026 |
|
027 |
map
= new HashMap<String,
Object>(); |
028 |
map.put( "title" , "G2" ); |
029 |
map.put( "info" , "google
2" ); |
030 |
map.put( "img" ,
R.drawable.i2); |
031 |
list.add(map); |
032 |
|
033 |
map
= new HashMap<String,
Object>(); |
034 |
map.put( "title" , "G3" ); |
035 |
map.put( "info" , "google
3" ); |
036 |
map.put( "img" ,
R.drawable.i3); |
037 |
list.add(map); |
038 |
|
039 |
return list; |
040 |
} |
041 |
|
042 |
//
ListView 中某項被選中後的邏輯 |
043 |
@Override |
044 |
protected void onListItemClick(ListView
l, View v, int position, long id)
{ |
045 |
|
046 |
Log.v( "MyListView4-click" ,
(String)mData.get(position).get( "title" )); |
047 |
} |
048 |
|
049 |
/** |
050 |
*
listview中點擊按鍵彈出對話框 |
051 |
*/ |
052 |
public void showInfo(){ |
053 |
new AlertDialog.Builder( this ) |
054 |
.setTitle( "我的listview" ) |
055 |
.setMessage( "介紹..." ) |
056 |
.setPositiveButton( "確定" , new DialogInterface.OnClickListener()
{ |
057 |
@Override |
058 |
public void onClick(DialogInterface
dialog, int which)
{ |
059 |
} |
060 |
}) |
061 |
.show(); |
062 |
|
063 |
} |
064 |
|
065 |
|
066 |
|
067 |
public final class ViewHolder{ |
068 |
public ImageView
img; |
069 |
public TextView
title; |
070 |
public TextView
info; |
071 |
public Button
viewBtn; |
072 |
} |
073 |
|
074 |
|
075 |
public class MyAdapter extends BaseAdapter{ |
076 |
|
077 |
private LayoutInflater
mInflater; |
078 |
|
079 |
|
080 |
public MyAdapter(Context
context){ |
081 |
this .mInflater
= LayoutInflater.from(context); |
082 |
} |
083 |
@Override |
084 |
public int getCount()
{ |
085 |
//
TODO Auto-generated method stub |
086 |
return mData.size(); |
087 |
} |
088 |
|
089 |
@Override |
090 |
public Object
getItem( int arg0)
{ |
091 |
//
TODO Auto-generated method stub |
092 |
return null ; |
093 |
} |
094 |
|
095 |
@Override |
096 |
public long getItemId( int arg0)
{ |
097 |
//
TODO Auto-generated method stub |
098 |
return 0 ; |
099 |
} |
100 |
|
101 |
@Override |
102 |
public View
getView( int position,
View convertView, ViewGroup parent) { |
103 |
|
104 |
ViewHolder
holder = null ; |
105 |
if (convertView
== null )
{ |
106 |
|
107 |
holder= new ViewHolder(); |
108 |
|
109 |
convertView
= mInflater.inflate(R.layout.vlist2, null ); |
110 |
holder.img
= (ImageView)convertView.findViewById(R.id.img); |
111 |
holder.title
= (TextView)convertView.findViewById(R.id.title); |
112 |
holder.info
= (TextView)convertView.findViewById(R.id.info); |
113 |
holder.viewBtn
= (Button)convertView.findViewById(R.id.view_btn); |
114 |
convertView.setTag(holder); |
115 |
|
116 |
} else { |
117 |
|
118 |
holder
= (ViewHolder)convertView.getTag(); |
119 |
} |
120 |
|
121 |
|
122 |
holder.img.setBackgroundResource((Integer)mData.get(position).get( "img" )); |
123 |
holder.title.setText((String)mData.get(position).get( "title" )); |
124 |
holder.info.setText((String)mData.get(position).get( "info" )); |
125 |
|
126 |
holder.viewBtn.setOnClickListener( new View.OnClickListener()
{ |
127 |
|
128 |
@Override |
129 |
public void onClick(View
v) { |
130 |
showInfo(); |
131 |
} |
132 |
}); |
133 |
|
134 |
|
135 |
return convertView; |
136 |
} |
137 |
|
138 |
} |
139 |
|
140 |
|
141 |
|
142 |
|
143 |
} |
下面將對上述代碼,做詳細的解釋,listView在開始繪製的時候,系統首先調用getCount()函數,根據他的返回值得到listView的長度(這也是爲什麼在開始的第一張圖特別的標出列表長度),然後根據這個長度,調用getView()逐一繪製每一行。如果你的getCount()返回值是0的話,列表將不顯示同樣return 1,就只顯示一行。
系統顯示列表時,首先實例化一個適配器(這裏將實例化自定義的適配器)。當手動完成適配時,必須手動映射數據,這需要重寫getView()方法。系統在繪製列表的每一行的時候將調用此方法。getView()有三個參數,position表示將顯示的是第幾行,covertView是從佈局文件中inflate來的佈局。我們用LayoutInflater的方法將定義好的vlist2.xml文件提取成View實例用來顯示。然後將xml文件中的各個組件實例化(簡單的findViewById()方法)。這樣便可以將數據對應到各個組件上了。但是按鈕爲了響應點擊事件,需要爲它添加點擊監聽器,這樣就能捕獲點擊事件。至此一個自定義的listView就完成了,現在讓我們回過頭從新審視這個過程。系統要繪製ListView了,他首先獲得要繪製的這個列表的長度,然後開始繪製第一行,怎麼繪製呢?調用getView()函數。在這個函數裏面首先獲得一個View(實際上是一個ViewGroup),然後再實例並設置各個組件,顯示之。好了,繪製完這一行了。那 再繪製下一行,直到繪完爲止。在實際的運行過程中會發現listView的每一行沒有焦點了,這是因爲Button搶奪了listView的焦點,只要佈局文件中將Button設置爲沒有焦點就OK了。
運行效果如下圖: