Wierd 列表视图项目选择器外观(手指离开屏幕时未删除按下状态)



>我有如下所示的列表视图项目

<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_UPACTION_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 >

最新更新