我正在使用Relative Layout
以及TextViews等中的许多按钮。除非发生某些事件,否则我希望所有按钮都不是clickable
。
我尝试设置RelativeLayout.setClickable(false);
,但布局中的所有元素仍为clickable
。
我知道这样做的一种方法是设置每个子元素而不是clickable
,但这不是一种合适的方式,因为我在布局中有很多子元素,如按钮文本视图等,我不能让每个孩子都无法点击
我的问题是如何在setClickable(false);
中将所有内容设置为layout
?
答案 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
。答案 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