3

我有如下列表视图项目

<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,则接收到sequence event,但是listview的onItemClick不起作用。我尝试阅读 AbsListview 中的 onTouch 代码片段以了解如何解决问题,我发现有时通过调用 child.setPressed(false),child(item) 的按下状态不会清除为 false,这取决于不同的触摸模式。

我真的很想要一个解决方案!!!

4

5 回答 5

2
<?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>

尝试使用这些选择器作为背景

于 2012-04-28T04:23:19.540 回答
1

尝试使其内部的视图无法聚焦...

<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"
    />

您不能在触摸模式下使列表项成为焦点...这里因为您的复选框是可聚焦的,所以会产生问题...

于 2012-04-24T07:46:34.497 回答
1

我解决了这个问题,但可能不是一个好的解决方案或官方解决方案。

我使用我自己的MyListView类 extends fromListView而不是 SDK并在其中ListView接收ACTION_UPand ,然后手动将项目的按下状态设置为 false 。更多细节请看下面的代码。ACTION_CANCELonTouchEvent

@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;
}
于 2012-05-02T03:38:38.417 回答
0

您应该尝试使用这样的默认选择器项

<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />

这将处理所有剩余的状态,或者您应该有一个选择器项来处理focussed您的 xml 中缺少的状态。

于 2012-04-24T13:31:59.293 回答
0

扩展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 >
于 2012-04-27T04:42:08.943 回答