Android AdvancedRecyclerView SwitchButton 阻止点击进入父布局

标签 android android-layout listview android-fragments

这将是一个棘手的问题,但不是对你们来说,而是对我来说。

解释我想要什么会很困难,所以请耐心等待。

我正在使用 AdvancedRecyclerView 库,特别是 Draggable 和 Swipping 库

这是我为列表中的每个项目使用的布局:

<?xml version="1.0" encoding="utf-8"?>
<!--
       Copyright (C) 2015 Haruki Hasegawa

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

           http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
-->
<!-- NOTE: should use FrameLayout or RelativeLayout for parent of the "@id/container" view (for Android 2.3 compatibility) -->
<FrameLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/commonListItemStyle"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="96dp"
    android:layout_margin="4dp"
    android:background="@drawable/bg_swipe_item_neutral">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:foreground="?attr/selectableItemBackground"
        tools:ignore="UselessParent">

        <LinearLayout
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <View
                android:id="@+id/statusBar"
                android:layout_width="match_parent"
                android:layout_height="5dp"
                android:layout_gravity="top|left"
                android:background="#20000000"
                android:visibility="gone" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@drawable/list_divider_v"
                android:orientation="horizontal">

                <View
                    android:id="@+id/drag_handle"
                    android:layout_width="15dp"
                    android:layout_height="match_parent"
                    android:layout_gravity="top|left"
                    android:background="@color/material_grey300"
                    android:visibility="visible" />

                <LinearLayout
                    android:layout_width="244dp"
                    android:layout_height="match_parent"
                    android:divider="@drawable/list_divider_v"
                    android:dividerPadding="4dp"
                    android:orientation="vertical"
                    android:showDividers="middle"
                    android:weightSum="3">

                    <TextView
                        android:id="@+id/deviceName"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_weight="2"
                        android:gravity="center_vertical|center_horizontal"
                        android:text="deviceName" />

                    <TextView
                        android:id="@+id/deviceDescription"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center_vertical|center_horizontal"
                        android:text="deviceDescription" />

                </LinearLayout>

                <com.kyleduo.switchbutton.SwitchButton
                    android:id="@+id/turnOn"
                    style="@style/SwitchButtonStyle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    app:kswBackMeasureRatio="2.2"
                    app:kswBackRadius="2dp"
                    app:kswTextOff="Off"
                    app:kswTextOn="On"
                    app:kswThumbRadius="2dp" />

            </LinearLayout>
        </LinearLayout>

    </FrameLayout>

</FrameLayout>

此布局文件中最重要的内容是 ID 为 containerFrameLayout 以及最后 ID 为 turnOn 的 SwitchButton

容器上和SwitchButton中有一个ClickListener。第一个触发另一个 Fragment,第二个仅触发 Switch。

问题是,如果 SwitchButton 无法单击或滑动,则单击操作将转到容器,而这不是我想要的。我尝试了代码中的所有内容,但我认为我的问题出在布局文件中......

例如:如果 SwitchButton 被阻止单击或滑动,则用户不应该能够对该按钮执行任何操作,但实际情况是当用户单击被阻止的按钮时单击将转到容器,并且将执行不需要的内容。

注意:即使SwitchButton被阻止,用户本身也可以选择点击容器,但我不希望>容器在被阻止的按钮中单击时被触发。

如果你们需要有关我将在此处提供的代码的更多信息,我会尽力解释我的问题。

一如既往地感谢, 伊戈尔·莫尔斯。

最佳答案

问题

您的问题来自于 SwitchButton 库的实现。

当您将 View.OnClickListener 附加到 SwitchButton 并启用开关时,一切都会按预期工作,因为点击会转到该点击监听器。但是,当开关被禁用时,点击将转到 SwitchButtononTouchEvent() 实现。这是该方法的第一部分(来自 SwitchButton source 代码):

@Override
public boolean onTouchEvent(MotionEvent event) {

    if (!isEnabled() || !isClickable() || !isFocusable()) {
        return false;
    }

如果您查看 onTouchEvent() 的文档,您会发现:

Returns: True if the event was handled, false otherwise.

因此 SwitchButton 库明确表示它处理点击,并且这些点击应该在 View 层次结构中向上冒泡。

解决方案

我看到两个相对简单的解决方案。

第一个是创建您自己的 SwitchButton 的自定义子类,并更改 onTouchEvent() 以在禁用时消耗点击:

public class MySwitchButton extends SwitchButton {

    public MySwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !isEnabled() || super.onTouchEvent(event);
    }
}

第二种方法是将您的 SwitchButton 包装在另一个 View 中,并为该包装器分配一个 View.OnClickListener 以拦截点击事件:

<FrameLayout
    android:id="@+id/interceptor"
    ...>

    <com.kyleduo.switchbutton.SwitchButton
        .../>

</FrameLayout>

在 Java 中:

findViewById(R.id.interceptor).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // do nothing
    }
});

就我个人而言,我更喜欢第一个。

关于Android AdvancedRecyclerView SwitchButton 阻止点击进入父布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45745168/

相关文章:

java - Android - 解析图像 url 的 Twitter JSON

android - 带有 Retrofit gradle 问题的简单 XML

android - 小米红米 Note 4X "Install via usb"抛出 "Insert your SIM card"

android - 布局中的三角形 - Android UI

android - 嵌套权重不利于性能

C#:如何在虚拟模式下有效地过滤(隐藏)ListView 项目?

java - 如何在程序运行时更新GUI?

java - 将数据从 map 添加到 Java FX ListView?

android - 如何在适配器的自定义 ListView 中设置所有图像可见性的功能?

android - 相对布局中的线性布局?