Android布局使所有孩子都无法点击

时间:2014-01-14 06:27:06

标签: android

我正在使用Relative Layout以及TextViews等中的许多按钮。除非发生某些事件,否则我希望所有按钮都不是clickable

我尝试设置RelativeLayout.setClickable(false);,但布局中的所有元素仍为clickable

我知道这样做的一种方法是设置每个子元素而不是clickable,但这不是一种合适的方式,因为我在布局中有很多子元素,如按钮文本视图等,我不能让每个孩子都无法点击

我的问题是如何在setClickable(false);中将所有内容设置为layout

12 个答案:

答案 0 :(得分:22)

当你说点击时,你实际上是指触摸吗?触摸事件是逐个元素完成的。他们首先被发送到最高级别,这表示如果它处理了它,如果它没有处理,它会进入视图中的每个孩子。

当创建触摸事件时,调用链中的onTouch视图方法,如果其中任何一个返回true(true表示“我处理了这个!”),它将停止向孩子们发送。< / p>

要让你的relativelayout块触及所有孩子的触摸和点击,你只需要设置onTouchListener,如下所示:

YOUR_RELATIVE_LAYOUT.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // ignore all touch events
        return true;
    }
});

这将忽略相对布局(及其所有子项)上发生的所有触摸事件,包括简单的触摸然后发布事件(称为点击)。

答案 1 :(得分:13)

我找到了另一种方法来实现这一目标。你可以在RelativeLayout的所有兄弟视图的顶部创建一个阻塞的LinearLayout,如下所示:

System.Drawing.FontStyle.Bold

稍后您可以将LinearLayout的可见性切换为GONE,以允许再次点击子视图:

<RelativeLayout
    android:id="@+id/rl_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- the children views begins -->
    ...
    <!-- the children views ends -->

    <LinearLayout
        android:id="@+id/ll_mask"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:clickable="true"
        android:orientation="horizontal"
        android:visibility="visible"/>

</RelativeLayout>

答案 2 :(得分:11)

您可以使用以下功能查找所有子视图并取消单击。

  public void setClickable(View view) {
    if (view != null) {
        view.setClickable(false);
        if (view instanceof ViewGroup) {
            ViewGroup vg = ((ViewGroup) view);
            for (int i = 0; i < vg.getChildCount(); i++) {
                setClickable(vg.getChildAt(i));
            }
        }
    }
}

答案 3 :(得分:3)

一种非常简单且完全证明的方法是创建子类并覆盖onInterceptTouchEvent

public class MyRelativeLayout extends RelativeLayout {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // true if you do not want the children to be clickable.
        return mShouldInterceptAllTouch;
    }
}

无需拨打任何儿童的方法。

您仍然可以在setOnClickListener对象上拨打myRelativeLayout。此外,您可以在XML中使用该类,就像使用RelativeLayout

一样

答案 4 :(得分:1)

由于您要在执行该特定功能时对布局中的某些项执行单击,

  • 您可以保留一个类似布尔值的静态标志
  • 全局创建一个静态布尔值并将其声明为false,执行特定功能后将其更改为true
  • 所以在你执行的所有onclick函数中检查这个标志是否为true执行必需功能。

答案 5 :(得分:1)

如果使用Butterknife库,可以对视图进行分组,并且可以在组上完成功能。 请参阅http://jakewharton.github.io/butterknife/

@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;

apply方法允许您一次对列表中的所有视图执行操作。

ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);

Action和Setter接口允许指定简单行为。

static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
  @Override public void apply(View view, int index) {
    view.setEnabled(false);
  }
};

static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
  @Override public void set(View view, Boolean value, int index) {
    view.setEnabled(value);
  }
};

例如,如果文本视图已分组,则可以

static final ButterKnife.Setter<TextView, Boolean> ENABLED = new ButterKnife.Setter<TextView, Boolean>() {
        @Override public void set(TextView view, Boolean value, int index) {
            view.setClickable(value);
            view.setLongClickable(value);
            if(value){
                view.setTextColor(color);
            } else {
                view.setTextColor(color);
            }
        }
    };

答案 6 :(得分:1)

如果您希望ViewGroup的孩子对触摸事件没有反应,但您希望ViewGroup本身响应点击次数,例如,您可以创建自己的ViewGroup子类,覆盖onInterceptTouchEvent(),并始终返回true。这会在儿童看到之前拦截所有触摸事件,同时允许您的自定义ViewGroup保持对触摸事件的响应。

因此,您可以使用自己的子类代替RelativeLayout

public class ControlFreakRelativeLayout extends RelativeLayout {
    private boolean mWithholdTouchEventsFromChildren;

    // Constructors omitted for sake of brevity

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mWithholdTouchEventsFromChildren || super.onInterceptTouchEvent(ev);
    }

    public void setWithholdTouchEventsFromChildren(boolean withholdTouchEventsFromChildren) {
        mWithholdTouchEventsFromChildren = withholdTouchEventsFromChildren;
    }
}

答案 7 :(得分:1)

作为一种替代方法,您可以通过FrameLayout而不是RelativeLayout来创建带有子视图的可单击ViewGroup。只需使用填充和重力将您的子视图放置在FrameLayout中,使FrameLayout可点击,而所有子视图均不可点击:

<FrameLayout
    android:layout_width="51dp"
    android:layout_height="59dp"
    android:layout_gravity="center"
    android:clickable="true"
    android:focusable="true"
    android:onClick="@{() -> activity.onClick()}"
    android:padding="5dp">

    <android.support.v7.widget.AppCompatImageButton
        android:layout_width="wrap_content"
        android:layout_height="29dp"
        android:layout_gravity="center"
        android:clickable="false"
        app:srcCompat="@drawable/ic_back" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:layout_marginBottom="5dp"
        android:layout_marginLeft="5dp"
        android:clickable="false"
        android:text="@string/back" />
</FrameLayout>

答案 8 :(得分:1)

一种简单的 Kotlin扩展解决方案,用于禁用/启用视图及其所有子视图:

fun View.isUserInteractionEnabled(enabled: Boolean) {
    isEnabled = enabled
    if (this is ViewGroup && this.childCount > 0) {
        this.children.forEach {
            it.isUserInteractionEnabled(enabled)
        }
    }
}

并调用:

view.isUserInteractionEnabled(false)

答案 9 :(得分:0)

您可以创建一个通用的方法,在其中编写代码以禁用相对布局中的所有视图,并在onCreate()中调用此方法,然后您可以在事件的布局中启用特定视图

答案 10 :(得分:0)

循环按钮并使用setClickable函数并为其传递false值。 然后当你甚至在ot上再次发生循环并且setClickable为真时

答案 11 :(得分:0)

问题:与原始问题相同,但用例不同。我想对带有透明背景颜色的容器中的progressBar小部件进行操作。我想禁用对我透明背景色下的其他项目的所有点击。

解决方案:只需在我的案例中将您的容器设置为可点击相对布局,它也可以设置任何其他布局,使您的布局可点击为true,直到您希望根据我的情况直到api调用完成为止。只需将您的父项设置为clickable即可。

android xml

<RelativeLayout
android:id="@+id/rl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- the children views begins -->
...
<!-- the children views ends -->


</RelativeLayout>

Java:

rl_parent.setClickable(true); // when to disable all clicks of children view

rl_parent.setClickable(false); // when to enable all clicks of children view