Android Wierd listview项目选择器外观(手指离开屏幕时按下的状态未被移除)
我有如下列表视图项Android Wierd listview项目选择器外观(手指离开屏幕时按下的状态未被移除),android,android-layout,android-widget,android-listview,Android,Android Layout,Android Widget,Android Listview,我有如下列表视图项 <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"
<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>
当我按下listview中的项目并将触摸屏留在项目内时,根据不同的状态绘制的是右侧
问题:但如果我按下该项并将手指水平移出该项(触摸点的X位于该项的顶部和底部之间),然后离开屏幕,复选框的可绘制状态将保持在按下状态。(如果触摸点的X超出项目的顶部和底部,则状态为正确)
我尝试将android:duplicateParentState=“true”
添加到复选框中,以获得与父项相同的状态,但不起作用
我很困惑,有人有什么想法吗
已编辑
我之前尝试过在项目中实现onTouch和onIntercept,但只有在返回super.onTouch(MotionEvent)时才能接收到action down。仅返回true,则将接收序列事件,但listview的onItemClick无法工作。
我试图阅读AbsListview中的onTouch代码片段以找出解决问题的方法,我发现有时通过调用child.setPressed(false),child(item)的按下状态不会清除为false,这取决于不同的触摸模式
我真的很想要一个解决方案 尝试使其内部的视图不可聚焦
<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"
/>
您无法使列表项在触摸模式下可聚焦。。。在这里,由于您的复选框是可聚焦的,因此会产生问题 您应该尝试使用如下默认选择器项
<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
这将照顾到所有剩下的州
或者,您应该有一个选择器项,用于处理xml中缺少的
聚焦状态。扩展项目的线性布局,并覆盖其中的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);
}
}
提及
希望有帮助
<ItemLayout
....>
<TextView
...
/>
<CheckBox
...
/>
</ItemLayout >
尝试使用这些选择器作为背景我解决了问题,但可能不是一个好的解决方案或正式的解决方案
我使用我自己的MyListView
类扩展自ListView
而不是SDKListView
,并在其onTouchEvent
中接收ACTION\u UP
和ACTION\u 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;
}
这是一个纯粹的猜测,但可能是因为该运动在视图(按下)上注册了一个向下事件,而不是该视图对应的向上事件?我尝试了,但它不起作用。我使用android:genderantfocusability=“blocksDescendants”来避免项目聚焦。@dreamtale。。尝试删除我认为它甚至不是必需的,因为ListView项无法保持选中状态。我删除了,并尝试了与您发布的代码相同的代码,但仍然不起作用。这个问题让我很沮丧。我问一位工程师,他发现他的gridview也有同样的问题。可能listview或gridview想要与您之前编写的效果相同的效果,但存在相同的问题。我已经尝试过,但它不起作用,Android lint还有一个警告:在2上找不到Android:state_uu属性,后面的状态无法访问。我在最后有这个,也就是在所有其他选择器状态之后。我不知道这是否有区别。你也试过状态聚焦吗?看到警告后,我试着把它移到最后,但不幸的是它仍然不起作用,这个问题让我发疯。我已经尝试了2个小时。我解决了这个问题,但可能不是一个好的解决方案或正式的解决方案。我的listview项当前是extends LinearLayout,我以前尝试过实现onTouch和onIntercept,但只能接收到action down,如果我返回super.onTouch(MotionEvent事件),只返回true,则会接收序列事件,但是listview的onItemClick无法工作。如果返回super,则在该项中只能接收到操作down。是否按照我给出的代码中的方法执行此操作?查看google groups链接,上面说手指消失时会执行取消操作。我以前尝试过,记住取消操作没有收到,我会稍后再试,如果收到,会通知你。不,取消操作也无法收到。我几乎放弃了,过一段时间,我会再次尝试解决它。如果在实现ontouch和on后上述操作不起作用,请识别操作启动事件并使用适配器刷新listview。notifyDataSetChanged()我解决了问题,但可能不是一个好的解决方案或正式的解决方案。
<?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>
@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;
}