Android ExpandableListView長按事件的完美解決辦法
更新時(shí)間:2013年06月15日 11:05:05 作者:
本篇文章是對Android中ExpandableListView長按事件的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
關(guān)于ExpandableListView長按事件處理,網(wǎng)上很多都是使用將上下文菜單注冊到ExpandableListView上實(shí)現(xiàn)長按事件。
這樣做弊端顯而易見,不夠靈活,不能分別對父項(xiàng)、子項(xiàng)、父項(xiàng)之間、子項(xiàng)之間彈出內(nèi)容做區(qū)分。
下面來說我的解決方法,方法有點(diǎn)投機(jī)取巧。首先說明一點(diǎn),使用我這種方法必須使用自定義的BaseExpandableListAdapter,至于為什么,具體后面講到。
ExpandableListView本身有繼承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
實(shí)現(xiàn)監(jiān)聽器:
/**
* 長按郵箱快捷選項(xiàng)
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
//pos不可用說明見下文
return false;
}
}
如果這個(gè)方法是用在ListView長按事件中剛剛好,但在ExpandableListView中,第三個(gè)參數(shù)pos不能區(qū)分開點(diǎn)擊的是父項(xiàng)還是子項(xiàng),以及哪個(gè)父項(xiàng)或子項(xiàng)。
在ExpandableListView響應(yīng)的onItemLongCkick方法中,pos參數(shù)值為:從上到下,父項(xiàng)+展現(xiàn)的子項(xiàng)到點(diǎn)擊位置的數(shù)目(注意:是展現(xiàn)的,隱藏的子項(xiàng)不包括,從0開始)。
例如:
父項(xiàng)1(隱藏3個(gè)子項(xiàng))
父項(xiàng)2
|—子項(xiàng)2-0
|—子項(xiàng)2-1
|—子項(xiàng)2-2
長按子項(xiàng)2-1時(shí),pos值為3。顯然根據(jù)pos值是無法確定點(diǎn)擊的是哪個(gè)子項(xiàng)或父項(xiàng)的。
因此依賴pos是很難處理點(diǎn)擊位置的。
如果可以直接在onItemLongClick方法中獲取groupPos,及childPos該多好呢?
于是看到了onItemLongClick方法第二個(gè)參數(shù):view。這里的view是你按中的位置對應(yīng)的view。view有個(gè)方法getTag(int key)。如果在創(chuàng)建此view的時(shí)候就把groupPos,childPos通過setTag(int key, Object value)設(shè)置進(jìn)去,在響應(yīng)onItemLongClick不就可以直接拿出來用了么。
現(xiàn)在就要講到必須使用自定義的BaseExpandableListAdapter的理由了。
要把groupPos,childPos通過setTag的方式綁定到view中,就必須操作該view的創(chuàng)建過程。要控制這個(gè)過程就必須要在自定義BaseExpandableListAdapter中重寫getGroupView及getChildView方法進(jìn)行操作。如下:
public class AccountListAdapter extends BaseExpandableListAdapter {
...省略其他方法
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//我這里僅通過自己寫的mkChildView()方法創(chuàng)建TextView來顯示文字,更復(fù)雜的可以通過LayoutInflater來填充一個(gè)view
TextView childTv = mkChildView();
// 標(biāo)記位置
// 必須使用資源Id當(dāng)key(不是資源id會(huì)出現(xiàn)運(yùn)行時(shí)異常),android本意應(yīng)該是想用tag來保存資源id對應(yīng)組件。
// 將groupPosition,childPosition通過setTag保存,在onItemLongClick方法中就可以通過view參數(shù)直接拿到了!
childTv.setTag(R.id.xxx01, groupPosition);
childTv.setTag(R.id.xxx02, childPosition);
return childTv;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TextView groupTv = mkGroupView();
// 設(shè)置同getChildView一樣
groupTv.setTag(R.id.xxx01, groupPosition);
groupTv.setTag(R.id.xxx02, -1); //設(shè)置-1表示長按時(shí)點(diǎn)擊的是父項(xiàng),到時(shí)好判斷。
groupTv.setText(groups[groupPosition]);
return groupTv;
}
}
完成了這一步,我們只需要在ExpandableListView響應(yīng)的onItemLongClick方法時(shí)通過view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
如下:
/**
* 長按郵箱快捷選項(xiàng)
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //參數(shù)值是在setTag時(shí)使用的對應(yīng)資源id號
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//長按的是父項(xiàng)
//根據(jù)groupPos判斷你長按的是哪個(gè)父項(xiàng),做相應(yīng)處理(彈框等)
} else {
//根據(jù)groupPos及childPos判斷你長按的是哪個(gè)父項(xiàng)下的哪個(gè)子項(xiàng),然后做相應(yīng)處理。
}
return false;
}
}
到這就寫完了,貌似比較啰嗦。重寫B(tài)aseExpandableListAdapter寫的比較簡潔,沒看明白的朋友可以先到網(wǎng)上查下怎么自定義BaseExpandableListAdapter,和自定義BaseAdapter其實(shí)是一樣的。
這樣做弊端顯而易見,不夠靈活,不能分別對父項(xiàng)、子項(xiàng)、父項(xiàng)之間、子項(xiàng)之間彈出內(nèi)容做區(qū)分。
下面來說我的解決方法,方法有點(diǎn)投機(jī)取巧。首先說明一點(diǎn),使用我這種方法必須使用自定義的BaseExpandableListAdapter,至于為什么,具體后面講到。
ExpandableListView本身有繼承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
實(shí)現(xiàn)監(jiān)聽器:
復(fù)制代碼 代碼如下:
/**
* 長按郵箱快捷選項(xiàng)
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
//pos不可用說明見下文
return false;
}
}
如果這個(gè)方法是用在ListView長按事件中剛剛好,但在ExpandableListView中,第三個(gè)參數(shù)pos不能區(qū)分開點(diǎn)擊的是父項(xiàng)還是子項(xiàng),以及哪個(gè)父項(xiàng)或子項(xiàng)。
在ExpandableListView響應(yīng)的onItemLongCkick方法中,pos參數(shù)值為:從上到下,父項(xiàng)+展現(xiàn)的子項(xiàng)到點(diǎn)擊位置的數(shù)目(注意:是展現(xiàn)的,隱藏的子項(xiàng)不包括,從0開始)。
例如:
父項(xiàng)1(隱藏3個(gè)子項(xiàng))
父項(xiàng)2
|—子項(xiàng)2-0
|—子項(xiàng)2-1
|—子項(xiàng)2-2
長按子項(xiàng)2-1時(shí),pos值為3。顯然根據(jù)pos值是無法確定點(diǎn)擊的是哪個(gè)子項(xiàng)或父項(xiàng)的。
因此依賴pos是很難處理點(diǎn)擊位置的。
如果可以直接在onItemLongClick方法中獲取groupPos,及childPos該多好呢?
于是看到了onItemLongClick方法第二個(gè)參數(shù):view。這里的view是你按中的位置對應(yīng)的view。view有個(gè)方法getTag(int key)。如果在創(chuàng)建此view的時(shí)候就把groupPos,childPos通過setTag(int key, Object value)設(shè)置進(jìn)去,在響應(yīng)onItemLongClick不就可以直接拿出來用了么。
現(xiàn)在就要講到必須使用自定義的BaseExpandableListAdapter的理由了。
要把groupPos,childPos通過setTag的方式綁定到view中,就必須操作該view的創(chuàng)建過程。要控制這個(gè)過程就必須要在自定義BaseExpandableListAdapter中重寫getGroupView及getChildView方法進(jìn)行操作。如下:
復(fù)制代碼 代碼如下:
public class AccountListAdapter extends BaseExpandableListAdapter {
...省略其他方法
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//我這里僅通過自己寫的mkChildView()方法創(chuàng)建TextView來顯示文字,更復(fù)雜的可以通過LayoutInflater來填充一個(gè)view
TextView childTv = mkChildView();
// 標(biāo)記位置
// 必須使用資源Id當(dāng)key(不是資源id會(huì)出現(xiàn)運(yùn)行時(shí)異常),android本意應(yīng)該是想用tag來保存資源id對應(yīng)組件。
// 將groupPosition,childPosition通過setTag保存,在onItemLongClick方法中就可以通過view參數(shù)直接拿到了!
childTv.setTag(R.id.xxx01, groupPosition);
childTv.setTag(R.id.xxx02, childPosition);
return childTv;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TextView groupTv = mkGroupView();
// 設(shè)置同getChildView一樣
groupTv.setTag(R.id.xxx01, groupPosition);
groupTv.setTag(R.id.xxx02, -1); //設(shè)置-1表示長按時(shí)點(diǎn)擊的是父項(xiàng),到時(shí)好判斷。
groupTv.setText(groups[groupPosition]);
return groupTv;
}
}
完成了這一步,我們只需要在ExpandableListView響應(yīng)的onItemLongClick方法時(shí)通過view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
如下:
復(fù)制代碼 代碼如下:
/**
* 長按郵箱快捷選項(xiàng)
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //參數(shù)值是在setTag時(shí)使用的對應(yīng)資源id號
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//長按的是父項(xiàng)
//根據(jù)groupPos判斷你長按的是哪個(gè)父項(xiàng),做相應(yīng)處理(彈框等)
} else {
//根據(jù)groupPos及childPos判斷你長按的是哪個(gè)父項(xiàng)下的哪個(gè)子項(xiàng),然后做相應(yīng)處理。
}
return false;
}
}
到這就寫完了,貌似比較啰嗦。重寫B(tài)aseExpandableListAdapter寫的比較簡潔,沒看明白的朋友可以先到網(wǎng)上查下怎么自定義BaseExpandableListAdapter,和自定義BaseAdapter其實(shí)是一樣的。
相關(guān)文章
Android ApplicationContext接口深入分析
ApplicationContext是Spring應(yīng)用程序中的中央接口,由于繼承了多個(gè)組件,使得ApplicationContext擁有了許多Spring的核心功能,如獲取bean組件,注冊監(jiān)聽事件,加載資源文件等2022-11-11
Android NDK開發(fā)簡單程序分享(Hello Word!)
本文主要對Android NDK開發(fā)簡單程序(Hello Word!)的實(shí)現(xiàn)步驟及方法進(jìn)行詳細(xì)介紹。具有很好的參考價(jià)值,需要的朋友一起來看下吧2016-12-12
Android studio實(shí)現(xiàn)畫板功能
這篇文章主要介紹了Android studio實(shí)現(xiàn)畫板功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Android WebView攔截iframe標(biāo)簽內(nèi)部跳轉(zhuǎn)教程
這篇文章主要介紹了Android WebView攔截iframe標(biāo)簽內(nèi)部跳轉(zhuǎn)教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android底部菜單欄(RadioGroup+Fragment)美化
這篇文章主要介紹了Android底部菜單欄RadioGroup+Fragment美化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
Android 實(shí)現(xiàn)會(huì)旋轉(zhuǎn)的餅狀統(tǒng)計(jì)圖實(shí)例代碼
這篇文章主要介紹了Android 實(shí)現(xiàn)會(huì)旋轉(zhuǎn)的餅狀統(tǒng)計(jì)圖實(shí)例代碼的相關(guān)資料,這里附有實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-12-12
Android ViewPager無限循環(huán)實(shí)現(xiàn)底部小圓點(diǎn)動(dòng)態(tài)滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android ViewPager無限循環(huán)實(shí)現(xiàn)底部小圓點(diǎn)動(dòng)態(tài)滑動(dòng)的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
Android開發(fā)中Intent.Action各種常見的作用匯總
今天小編就為大家分享一篇關(guān)于Android開發(fā)中Intent.Action各種常見的作用匯總,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12

