前幾天調試程序的時候遇到一個問題,使用ExpandableListView,需要獲取每個item,包括group和child 的單擊事件。
那么首先遇到的問題是,在ExpandableListView提供的接口,比如:
mLv.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { System.out.println("onItemLongClick"+arg2); return false; } });
里面只有一個arg2,是不足以區分該view是group還是child。在這里我用了View.setTag(key,value)方法,在BaseExpandableListViewAdapter中的getChildView和getGroupView中設置如下:
@Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildView childView = new ChildView(); convertView = View.inflate(context, R.layout.download_manager_explist_child, null); childView.img = (ImageView)convertView.findViewById(R.id.download_manager_explist_child_imgv); childView.title = (TextView)convertView.findViewById(R.id.download_manager_explist_child_title); childView.progress = (TextView)convertView.findViewById(R.id.download_manager_explist_child_progressInfo); childView.speed = (TextView)convertView.findViewById(R.id.download_manager_explist_child_speed);; childView.proBar = (ProgressBar)convertView.findViewById(R.id.download_manager_explist_child_probar); childView.btn = (Button)convertView.findViewById(R.id.download_manager_explist_child_button); childView.tempProBar = (LinearLayout)convertView.findViewById(R.id.download_manager_explist_child_tempProbar); //...中間代碼省略
convertView.setTag(R.id.expand_view_tagId,task.getTaskId());//設置childView的tagID為相應object的id convertView.setBackgroundResource(android.R.drawable.menuitem_background); return convertView; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { convertView = View.inflate(context, R.layout.download_manager_explist_group, null); GroupView groupView = new GroupView(); groupView.img = (ImageView)convertView.findViewById(R.id.download_manager_explist_group_imgv); groupView.tv = (TextView)convertView.findViewById(R.id.download_manager_explist_group_title); groupView.img.setBackgroundResource(groupList.get(groupPosition).getInt(IMG_ID)); String str = "("+getChildrenCount(groupPosition)+")"; groupView.tv.setText(groupList.get(groupPosition).getString(TITLE_MSG)+str); convertView.setTag(R.id.expand_view_tagId,-1);//設置group的TagID為-1 return convertView; }
然后在設置ExpLV的長按事件中:
mExpandLV.setOnItemLongClickListener(new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { final int id = (Integer)arg1.getTag(R.id.expand_view_tagId);//通過獲取Id來區分group和child if(id!=-1){ //在這里我設置如果id=-1,那么是groupItem,否則為child } return false; } });
至於R.id.expand_view_tagId的設置是在values/strings.xml的resource里面添加:
<item name="expand_view_tagId" type="id"/>
這樣能保證這個id的唯一性。
這就是設置區分group和child的一種方法。着這里要說明的是,上面的方法是我在網上搜到的一個blog,但是具體忘記地址了,這里只能對那位作者表示感謝了。
那么接下來還有一個問題是,在每個itemView中都包含其他的組件,特別是button,button和listView的共存問題在這里也是不可避免的需要解決,方法比較簡單,即:
在item的布局文件中的頂層Layout添加屬性:
android:descendantFocusability="blocksDescendants"
這個是設置該layout下面的子view無法獲取focus,我記得在測試的時候這設置就可以了,但是網上很多說法都是在button屬性里也要設置如下屬性:
android:focusable="false"
好了,一般listView下面這樣設置就ok了,但是頭痛的地方來了,在ExpandableListView里面,我調試的時候一直都是groupView可以獲取單擊事件的響應,而childView始終是無法獲得響應。一開始我就認定了是上面的和button的共存問題沒有解決好,使用圍繞這個問題去找解決的辦法,白白花費了一段時間去調試(杯具。。。)。后來才發現,原來是Adapter的問題,ExpandLV和普通的LV的適配器不同,那么這里的問題的關鍵就在於BaseExpandableListViewAdapter中有下面這么一個方法:
@Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; }
這個方法是設置childItem是否能被選中的,默認是返回false,現在設置return true后就解決問題了。由於之前用到ExpandLV的時候都不需要獲取item的單機響應事件,所以就理所當然的忽略了這個列在最后面的方法。。。
目前使用ExpandableListView遇到的問題也就這兩個吧,其他的還沒遇到或者是忘記了,以后如果有遇到的話再作記錄。