自定义ListView的时候经常要继承BaseAdapter,如果ListView的每个Item有自己独立的监听事件,比如Button,ImageButton之类的,这样很容易造成焦点冲突,往往造成Item的焦点被
子控件获取,而子控件又不响应事件。这时候可以用Android的descendantFocusability来处理,API中对descendantFocusability属性的解释:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
解决这个问题只需要用到blocksDescendants属性就行,即覆盖子类控件获取焦点,其实这个属性是加在Item布局的根节点上,同时给子控件加上 android:clickable="true"、
android:focusable="false"两个属性,这样的话每个Item都能优先于子控件获取焦点,子控件因为设置focusable为false,在初始化的时候不会获取焦点,clickable的属性让它处于可点
击的状态,这样一来Item的点击事件跟子控件的点击事件完全分开了。不过在Item里面慎用ImageButton,ImageButton用此种方式是解决不了,具体原因没去查,应该跟焦点优先程度有关
,很多人都遇到类似的问题,如果非要用ImageButton可以尝试用ImageView来代替。
如果子控件的background用了selector的话就必须得注意,在selector中尽量简化,直接设置android:state_pressed的状态就好,如果设置了android:state_focused等更焦点相关的属性极容易出问题。
android:listSelector属性是指item被选中状态的背景改变,这项要设成透明,否则会有干扰
ListView的点击效果只能设置在item_layout.xml的属性里面,这样综合应用就OK了
总结起来有4点:1、去子控件的焦点blocksDescendants、android:focusable并用
2、子控件不能有ImageButton
3、子控件的点击效果selector尽量不要加入焦点有关的属性,如focused等
4、去掉listview本身的点击效果,android:listSelector(选中效果)、android:cacheColorHint(滑动效果),每个item的点击效果要写在item的布局里面
item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="46dip" android:descendantFocusability="blocksDescendants" > <Button android:id="@+id/ItemImage" android:layout_width="40dip" android:layout_height="40dip" android:background="@drawable/back_btn_selector" android:layout_alignParentRight="true" android:clickable="true" android:focusable="false" android:layout_margin="2dip" /> <TextView android:id="@+id/diet_list_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_gravity="center_vertical" android:layout_toRightOf="@id/ItemImage" android:text="Defalut" android:textColor="#000" android:textSize="15dip" /> </RelativeLayout>
selector.xml
<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/back_btn_normal" android:state_pressed="true"></item> <item android:drawable="@drawable/back_btn_press" android:state_pressed="false"></item> </selector>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="46dip" android:descendantFocusability="blocksDescendants" > <Button android:id="@+id/ItemImage" android:layout_width="40dip" android:layout_height="40dip" android:background="@drawable/back_btn_selector" android:layout_alignParentRight="true" android:clickable="true" android:focusable="false" android:layout_margin="2dip" /> <TextView android:id="@+id/diet_list_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_gravity="center_vertical" android:layout_toRightOf="@id/ItemImage" android:text="Defalut" android:textColor="#000" android:textSize="15dip" /> </RelativeLayout>