前几天调试程序的时候遇到一个问题,使用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遇到的问题也就这两个吧,其他的还没遇到或者是忘记了,以后如果有遇到的话再作记录。