ListView的Item點擊事件(消息傳遞)

轉載請保留原文出處「http://my.oschina.net/gluoyer/blog」,謝謝!php

您能夠到博客的「友情連接」中,「程序猿媛(最新下載)*.*」下載最新版本,持續更新!當前版本,也可直接點擊「當前1.5版本」下載。java

 

    引子:自定義ListView的Adapter,給Item中的子控件(按鈕、圖標、文字等)添加點擊事件,來進行點擊後的不一樣處理,是常常要作的事情。但有些須要在處理事件中,對Activity中其餘控件進行更新的話,一般把Adapter在Activity中實現,處理比較多的話,在Activity中增長几百行代碼仍是比較廣泛的狀況。 個人習慣,仍是把Adapter獨立出來。那麼,其餘控件的更新如何處理呢?ide

 

    固然,每一個人的習慣不一樣,我這裏只是闡述一種思路,若是您以爲有用,能夠做爲參考;其餘就麻煩繞道吧。佈局

首先,仍是看下實現效果吧:this

e01 e02 e03 e04 e05

本文介紹:spa

    主要是經過Handler管理Message的方式,在Adapter處理點擊事件時,將所需數據傳送回所屬Activity。在Activity中處理點擊事件的後續操做的同時,又將Adapter獨立了出來,代碼結構就比較清晰,便於閱讀和管理了。.net

    Adapter的重寫,主要處理集中在getView方法中,這個想必你們都比較瞭解了,不贅述,請參見源代碼,代碼目錄結構以下:3d

X7WASOJK[YLH[)A_W6$Y2%T

    功能的實現比較簡單,主要是一種方式,主要兩部分:code

    1、在LiChildClickActivity中爲LiccAdapter設置Handler

    首先,在Activity中定義Handler,用於接收點擊事件返回的值:
?
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 ;
         }
     }
     
};
    其次,爲ListView設置帶有mHandle的LiccAdapter:
?
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

 

    2、在LiccAdapter中設置點擊事件,並經過Message將數據回傳

    首先,定義一些成員變量及靜態變量,保存數據,對應狀態:
?
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);
     }
     
}
    最後,在重寫的getView中,爲各個子元素設置監聽便可:
?
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的代碼行數一下減小了接近一半,總體代碼閱讀起來,仍是會舒服一些的吧。

 

——————————————————————————————————————

相關文章
相關標籤/搜索