【问题标题】:Issues with Button press states in each ListView row每个 ListView 行中的按钮按下状态问题
【发布时间】:2012-09-19 21:31:57
【问题描述】:

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

如果我从按钮的父/根布局 XML 中删除 android:descendantFocusability="blocksDescendants";那么按下状态将起作用,但无论您触摸 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" />

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

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

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

【问题讨论】:

标签: android listview button android-listview onclick


【解决方案1】:

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

这样会拦截触摸事件,子view不会被高亮。

在你的具体情况下:

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

【讨论】:

    【解决方案2】:

    你找到答案了吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多