【问题标题】:Android AdvancedRecyclerView SwitchButton Blocked Click going to Parent LayoutAndroid AdvancedRecyclerView SwitchButton Blocked Click to Parent Layout
【发布时间】:2017-08-17 21:25:07
【问题描述】:

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

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

我正在使用 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>

这个布局文件中最重要的是 FrameLayout id containerSwitchButton id 为 turnOn

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

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

例如:如果 SwitchButton 被阻止单击或滑动,则用户不应对该按钮执行任何操作,而是发生的情况是当用户单击被阻止的按钮时点击进入容器,执行不需要的操作。

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

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

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

【问题讨论】:

  • If the SwitchButton is blocked to click or swipe 你是如何实现这部分的?
  • 我刚刚使用 SwitchButton.setEnabled(false) 禁用了它,并确保我将 setClikable 设置为 true
  • 如果视图处于禁用状态(即spinner.setEnabled(false)android:enabled="false"),则不允许触摸事件向上移动。如果您仍然遇到该问题,请在 github 上发布一个具有该行为的简单项目。

标签: android android-layout listview android-fragments


【解决方案1】:

问题

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

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

@Override
public boolean onTouchEvent(MotionEvent event) {

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

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

返回: 如果事件被处理则为真,否则为假。

所以 SwitchButton 库明确表示它处理点击,这些点击应该在视图层次结构中冒泡。

解决方案

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

首先是创建您自己的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.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
    }
});

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

【讨论】:

  • 这很有趣!我确实查看了源代码,但没有注意这一点。是的,第一个解决方案更好,感谢您指出这一点,并感谢您对此事的完整回答。
猜你喜欢
  • 1970-01-01
  • 2012-12-04
  • 2015-03-16
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 2011-07-21
相关资源
最近更新 更多