轉載請保留原文出處「http://my.oschina.net/gluoyer/blog」,謝謝!php
您能夠到博客的「友情連接」中,「程序猿媛(最新下載)*.*」下載最新版本,持續更新!當前版本,也可直接點擊「當前1.5版本」下載。java
引子:自定義ListView的Adapter,給Item中的子控件(按鈕、圖標、文字等)添加點擊事件,來進行點擊後的不一樣處理,是常常要作的事情。但有些須要在處理事件中,對Activity中其餘控件進行更新的話,一般把Adapter在Activity中實現,處理比較多的話,在Activity中增長几百行代碼仍是比較廣泛的狀況。 個人習慣,仍是把Adapter獨立出來。那麼,其餘控件的更新如何處理呢?ide
固然,每一個人的習慣不一樣,我這裏只是闡述一種思路,若是您以爲有用,能夠做爲參考;其餘就麻煩繞道吧。佈局
首先,仍是看下實現效果吧:this
本文介紹:spa
主要是經過Handler管理Message的方式,在Adapter處理點擊事件時,將所需數據傳送回所屬Activity。在Activity中處理點擊事件的後續操做的同時,又將Adapter獨立了出來,代碼結構就比較清晰,便於閱讀和管理了。.net
Adapter的重寫,主要處理集中在getView方法中,這個想必你們都比較瞭解了,不贅述,請參見源代碼,代碼目錄結構以下:3d
功能的實現比較簡單,主要是一種方式,主要兩部分:code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private
Handler mHandle =
new
Handler() {
@Override
public
void
handleMessage(Message msg) {
LiData data = (LiData) msg.getData().getSerializable(LiccAdapter.BUNDLE_KEY_LIDATA);
switch
(msg.what) {
case
LiccAdapter.CLICK_INDEX_ITEM:
onItemClicked(msg.arg1, data);
break
;
case
LiccAdapter.CLICK_INDEX_COUNTRY:
onCountryClicked(data);
break
;
case
LiccAdapter.CLICK_INDEX_NAME:
onNameClicked(data);
break
;
}
}
};
|
1
2
3
4
5
6
7
8
9
|
// 獲取ListView
ListView lv = (ListView) findViewById(R.id.licc_list);
// 建立數據列表
ArrayList<LiData> list =
new
ArrayList<LiData>();
/**
填充列表數據代碼,請查看源碼 */
// 爲列表設置帶mHandle參數的LiccAdapter
LiccAdapter adapter =
new
LiccAdapter(
this
, mHandle, list);
lv.setAdapter(adapter);
|
這樣,在LiccAdapter中,處理點擊事件時發送的消息,就能夠在handleMessage中接收,並處理了。並且,onNameClicked等方法中,涉及到Activity中包含的一些成員,或佈局中的其餘控件時,就不用擔憂,在LiccAdapter中沒法調用了。blog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private
Context context;
// 點擊索引:點擊列表項;點擊按鈕;點擊名字。
protected
final
static
int
CLICK_INDEX_ITEM =
0
;
protected
final
static
int
CLICK_INDEX_COUNTRY =
1
;
protected
final
static
int
CLICK_INDEX_NAME =
2
;
// 記錄數據列表
private
ArrayList<LiData> list;
// 記錄Activity中接受消息的Handler
private
Handler mHandle;
// 關鍵字
protected
final
static
String BUNDLE_KEY_LIDATA =
"lidata"
;
// 構造方法
public
LiccAdapter(Context context, Handler handle, ArrayList<LiData> list) {
this
.context = context;
mHandle = handle;
this
.list =
new
ArrayList<LiData>();
for
(LiData data : list) {
this
.list.add(data);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
private
class
OnItemChildClickListener
implements
View.OnClickListener {
// 點擊類型索引,對應前面的CLICK_INDEX_xxx
private
int
clickIndex;
// 點擊列表位置
private
int
position;
public
OnItemChildClickListener(
int
clickIndex,
int
position) {
this
.clickIndex = clickIndex;
this
.position = position;
}
@Override
public
void
onClick(View v) {
// 建立Message並填充數據,經過mHandle聯繫Activity接收處理
Message msg =
new
Message();
msg.what = clickIndex;
msg.arg1 = position;
Bundle b =
new
Bundle();
b.putSerializable(BUNDLE_KEY_LIDATA, list.get(position));
msg.setData(b);
mHandle.sendMessage(msg);
}
}
|
1
2
3
4
5
6
7
8
9
10
|
// 這個holder,您懂的吧。
// 爲按鈕設置點擊事件監聽
holder.mCountry.setOnClickListener(
new
OnItemChildClickListener(CLICK_INDEX_COUNTRY, position));
// 爲名字設置點擊事件監聽
holder.mName.setOnClickListener(
new
OnItemChildClickListener(CLICK_INDEX_NAME, position));
// 設置列表項的監聽事件
convertView.setOnClickListener(
new
OnItemChildClickListener(CLICK_INDEX_ITEM, position));
|
Ok,如此,點擊列表項,及其設置了點擊監聽事件的子控件,就能夠將帶着數據的消息傳回Activity了。
固然,這裏看不出什麼優點,徹底能夠把LiccAdapter放到Activity裏面實現。但實際應用中,有些Activity須要處理的事情仍是比較多的,Adapter比較複雜的話,代碼量也是有一些的。
打個比方,一個2000行代碼的Activity,包含兩個各自500行代碼的自定義Adapter,若是剝離出來,Activity的代碼行數一下減小了接近一半,總體代碼閱讀起來,仍是會舒服一些的吧。
——————————————————————————————————————