首页 > 解决方案 > LinearLayout 被用作按钮卡在按下状态

问题描述

我正在为电话拨号器构建自定义布局。对于拨号器中的每个号码,我都在使用带有一些 TextView 的 LinearLayout。

问题:当 anonClickListener设置为自定义 LinearLayout 并且随后被用户按下时,它会卡在按下状态并且释放时不会恢复到状态列表中的默认项。如果我没有onClickListener为 LinearLayout 设置一个,则状态会正确更改为已按下然后未按下。

通过 Android Studio 的布局检查器调试显示,LinearLayoutisPressed() == true在用户释放后仍然存在。我还尝试了 ImageButton 和 Button 而不是 LinearLayout,它表现出类似的行为。该应用程序的主题继承自Theme.MaterialComponents.Light.Bridge.

包含拨号按钮的片段布局:

 <TableLayout
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_gravity="center_horizontal"
            android:layout_weight="2">

        <TableRow
                android:layout_height="0px"
                android:layout_weight="1"
                android:gravity="center">

            <View
                    android:layout_width="1dp"
                    android:layout_height="match_parent"
                    android:background="#e2e2e2"/>

            <DialerButton
                    android:id="@+id/keypad2"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
...

用于 DialerButton 类(这是一个基本类,只是覆盖 LinearLayout 并扩展以下布局)的 LinearLayout 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:background="@drawable/dialpad_btn_background"
        android:clickable="true"
        android:focusable="true">

    <TextView
            android:id="@+id/tvNumeral"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="2"/>

    <TextView
            android:id="@+id/tvLettering"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="ABC"/>
</LinearLayout>

dialpad_btn_background.xml 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/dark_grey"/>
    <item android:drawable="@color/white"/>
</selector>

将 OnClickListener 附加到 LinearLayout 的代码是标准的:

 keypad1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
               /// ... Do work ...
            }
        });

标签: androidandroid-layout

解决方案


我无法找到使用布局解决此问题的方法,但我能够以编程方式解决它。这并没有解决为什么 LinearLayouts 或 ImageButtons 卡在按下状态,或者为什么状态列表没有按预期工作的根源。

首先,我重新使用 ImageButton 而不是自定义的 LinearLayout,因为这对按下状态没有影响。通过附加一个触摸监听器并以编程方式将 ImageButtons 的背景设置为MotionEvent.ACTION_UPand MotionEvent.ACTION_DOWN,我得到了我需要的结果。这是我如何做到这一点的片段:

 View.OnTouchListener touchListener = (v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                v.setBackground(getResources().getDrawable(R.drawable.img_dialpad_bg, null));
            }
            else if (event.getAction() == MotionEvent.ACTION_DOWN) {
                v.setBackground(getResources().getDrawable(R.drawable.img_dialpad_bg_pressed, null));
            }
            return false;
        };

keypad0.setOnTouchListener(touchListener);
keypad1.setOnTouchListener(touchListener);
...

推荐阅读