>我有如下所示的列表视图项目
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/music_list_item_checkbox_bg"
/>
</LinearLayout>
music_list_item_checkbox_bg.xml
是一个选择器,它将根据不同的状态显示不同的可绘制对象。
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_pressed="false"
android:state_selected="true"
android:drawable="@drawable/btn_checkbox_check_untapped" />
<item android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/btn_checkbox_check_tapped" />
<item android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
<item android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/btn_checkbox_uncheck_tapped" />
</selector>
当我在列表视图中按下项目并将触摸屏留在项目内部时,根据不同状态绘制的可绘制对象是正确的。
问:但是,如果我按下项目并将手指水平移出项目(触摸点的 X 位于项目的顶部和底部之间),然后离开屏幕,复选框的可绘制对象将保持按下状态。(如果触摸点的 X 不在项目的顶部和底部,则状态为正确)。
我尝试将android:duplicateParentState="true"
添加到复选框以获得与父级相同的状态,但它不起作用。
我很困惑,有人有一些想法吗?
编辑
我之前尝试在项目中实现onTouch和onIntercept,但如果我返回super.onTouch(MotionEvent事件),则只能接收操作。仅返回 true,然后序列事件将收到,但列表视图的 onItemClick 不起作用。 我尝试阅读AbsListview中的onTouch代码片段以找出解决问题的方法,我发现有时child(item)的按压状态不会通过调用child.setPressed(false)来清除为false,这取决于不同的触摸模式。
我真的真的想要一个解决方案!!
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_checkbox_check_tapped" />
<item android:state_selected="true"
android:drawable="@drawable/btn_checkbox_check_tapped" />
<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
</selector>
尝试使用这些选择器作为背景
尝试使其内部的视图不可聚焦...
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/music_list_item_checkbox_bg"
android:focussableInTouchMode="false"
android:focussable="false"
/>
您无法使列表项在触摸模式下可聚焦...在这里,由于您的复选框是可聚焦的,因此会产生问题...
我解决了问题,但可能不是一个好的解决方案或官方解决方案。
我使用自己的MyListView
类从ListView
扩展而不是SDK ListView
并在其onTouchEvent
中接收ACTION_UP
和ACTION_CANCEL
,然后手动将项目的按下状态设置为false。有关更多详细信息,请参阅以下代码。
@Override
public boolean onTouchEvent(MotionEvent event)
{
boolean handled = super.onTouchEvent(event);
Log.d("test", "event " + event.toString());
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
m_downPosition = pointToPosition((int)event.getX(), (int)event.getY());
Log.d("test", "The down position " + m_downPosition);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
int position = m_downPosition - getFirstVisiblePosition();
View child = INVALID_POSITION != m_downPosition ? getChildAt(position) : null;
if (null != child)
{
child.setPressed(false);
}
break;
default:
break;
}
return handled;
}
你应该尝试使用这样的默认选择器项
<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
这将照顾所有剩余的状态或者,您应该有一个选择器项来处理XML中缺少的focussed
状态。
扩展项目的LinearLayout
并覆盖其中的onTouch
。处理ACTION_CANCEL事件(返回 true)并更新项目的按下和选定状态。
class ItemLayout extends LinearLayout {
@override
boolean onTouch(MotionEvent ev) {
switch(ev.getAction()) {
case ACTION_CANCEL:
// Update/reset pressed and selected states of item or checbkox
return true;
}
return super.onTouch(ev);
}
}
参考 http://groups.google.com/group/android-developers/browse_thread/thread/df75c5b8e4605167#
希望有帮助。
<ItemLayout
....>
<TextView
...
/>
<CheckBox
...
/>
</ItemLayout >