1

我在 ListView 行中按下按钮时遇到问题。每个 Button 的背景属性引用一个 XML 选择器文件;以便在按下按钮时选择不同的图像。我能够从 OnClickListener 获取新闻事件,但是状态选择器中断并且没有使用 android:state_pressed="true"and注册新闻android:state_focused="false"

如果我android:descendantFocusability="blocksDescendants"从按钮的父/根布局 XML 中删除;那么按下状态将起作用,但无论您触摸 ListView 行的哪个位置都会触发,这很烦人。

我的问题:无法管理与内部按钮分开的行的按下/默认状态。他们互相干扰。

代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/mainListLayout"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content" 
   android:descendantFocusability="blocksDescendants">
..........

行项目按钮进一步向下:

<Button
        android:id="@+id/deleteButton"
        android:background="@drawable/del_button_selector"
        .....
        .....
        />
..........

和drawable/del_button_selector:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/deleteico" android:state_focused="true" android:state_pressed="false"/>
    <item android:drawable="@drawable/deletepressed" android:state_focused="true" android:state_pressed="true"/>
    <item android:drawable="@drawable/deleteico" android:state_focused="false" android:state_pressed="true" />

在最后一个选择器行中更改可绘制背景不起作用。它将显示按下的图像,但无论您单击该行的哪个位置,远离按钮。

我可以更改按钮单击事件的背景,但我需要在按钮释放时切换回默认背景,这很难捕获(?)。如果我可以在侦听器中捕获按下/释放事件,那么这仅适用于按钮。

任何帮助表示赞赏!谢谢!

4

2 回答 2

3

简单的解决方案是设置android:clickable="true"为父视图。

这样它将拦截触摸事件,并且不会突出显示子视图。

在您的具体情况下:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/mainListLayout"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" 
      android:clickable="true">
于 2013-11-15T11:30:34.937 回答
1

你找到答案了吗?

我也遇到过这个问题。我认为 android 框架中存在错误(和/或我们面临 - 像往常一样 - 糟糕的框架设计)。但是有一个 xml 字段android:duplicateParentState在这种情况下没有用(说实话,我在另一个项目中使用它来复制父级的状态,将其设置为 true)。

所以我的解决方案是这样的(我知道它很丑,应该是一种更简单的方法):

  • 定义 2 个不同的可绘制对象:一个用于按下状态,一个用于未按下状态
  • 按钮的父级定义android:descendantFocusability="blocksDescendants"
  • onTouchListener在按钮上 设置一个

后者看起来像这样:

    button.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                v.setBackgroundDrawable(mButtonDownDrawable); // this call is deprecated since Jelly Bean, use setBackground() instead
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_OUTSIDE: // just in case. this is never called
            case MotionEvent.ACTION_CANCEL:
                v.setBackgroundDrawable(mButtonUpDrawable);
                break;
            case MotionEvent.ACTION_MOVE:
                final Rect rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
                if(!rect.contains((int)event.getX(), (int)event.getY())){
                    // User moved outside bounds
                    v.setBackgroundDrawable(mButtonUpDrawable);
                }
                break;
            }
            return false;
        }
    });
于 2013-03-01T15:55:09.243 回答