Android Layout 使所有孩子都不可点击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21107263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Layout make all children's not clickable
提问by Kasra Rahjerdi
I am using Relative Layout
and many buttons in it with TextViews etc.I want to make all of them not clickable
unless some event happens.
我正在使用 Relative Layout
TextViews 等中的许多按钮。clickable
除非发生某些事件,否则我想让所有按钮都不要。
I tried setting RelativeLayout.setClickable(false);
but still all the elements inside the layout are clickable
.
我尝试设置,RelativeLayout.setClickable(false);
但布局内的所有元素仍然是clickable
.
I know one way of doing it that setting each child element not clickable
but it is not an appropriate way because i have lot of child elements like buttons text views etc inside a layout i cannot make each child not clickable.
我知道一种不设置每个子元素的方法,clickable
但这不是一种合适的方法,因为我在布局中有很多子元素,例如按钮文本视图等,我无法使每个子元素都不可点击。
Here my question isHow to set all to setClickable(false);
in layout
??
这里我的问题是如何将所有设置为setClickable(false);
in layout
??
回答by Kasra Rahjerdi
When you say click do you actually mean touch? Touch events are done element by element. They're first sent to the top level, which says if it handled it and if it didn't it goes onto each children of the view.
当您说点击时,您实际上是指触摸吗?触摸事件是逐个元素完成的。它们首先被发送到顶层,如果它处理它,如果它没有处理它,它就会进入视图的每个子级。
When a touch event is created, the onTouch
method of view in the chain is called, if any of these return true (true meaning "I handled this!") it stops going down to the children.
当一个触摸事件被创建时,onTouch
链中的视图方法被调用,如果其中任何一个返回真(真意思是“我处理了这个!”),它就会停止传递给孩子。
To make your relativelayout block touches and clicks for all of its children you simply need to set the onTouchListener, like this:
要让您的相对布局块触摸和点击其所有子项,您只需设置 onTouchListener,如下所示:
YOUR_RELATIVE_LAYOUT.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// ignore all touch events
return true;
}
});
This will ignore all touch events happening on the relative layout (and all of its children) which includes simple touch down then release events (called clicks).
这将忽略在相对布局(及其所有子项)上发生的所有触摸事件,包括简单的触摸然后释放事件(称为点击)。
回答by David Cheung
I found an alternative way to achieve this. You may create a blocking LinearLayout on top all its sibling views in the RelativeLayout like below:
我找到了一种替代方法来实现这一目标。您可以在 RelativeLayout 中的所有兄弟视图之上创建一个阻塞 LinearLayout ,如下所示:
<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>
Later you may toggle the LinearLayout's visibility to GONE to allow the children views to be clickable again:
稍后您可以将 LinearLayout 的可见性切换为 GONE 以允许再次单击子视图:
mMask.setVisibility(View.VISIBLE); // blocks children
mMask.setVisibility(View.GONE); // children clickable
回答by vipul mittal
You can use following function to find all the child view and cancel click.
您可以使用以下功能查找所有子视图并取消单击。
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));
}
}
}
}
回答by vedant
A very simple and full-proof way to do it is to create a sub class and override onInterceptTouchEvent
:
一个非常简单且完全证明的方法是创建一个子类并覆盖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;
}
}
No need to call any of the children's methods.
无需调用任何孩子的方法。
You can still call setOnClickListener
on your myRelativeLayout
object. Also, you can use the class in XMLs as if you were using a RelativeLayout
您仍然可以调用setOnClickListener
您的myRelativeLayout
对象。此外,您可以在 XML 中使用该类,就像使用RelativeLayout
回答by Fragment
As an alternative way, you can make clickable ViewGroup with children views via FrameLayout instead of RelativeLayout. Just position your child views in FrameLayout using paddings and gravity, make FrameLayout clickable, and all children views non-clickable:
作为另一种方式,您可以通过 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>
回答by anoo_radha
If Butterknife library is used, the views can be grouped and the functionality can be done on the group. Refer http://jakewharton.github.io/butterknife/,
如果使用 Butterknife 库,则可以对视图进行分组,并且可以在组上完成功能。参考http://jakewharton.github.io/butterknife/,
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
The apply method allows you to act on all the views in a list at once.
apply 方法允许您一次对列表中的所有视图进行操作。
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
Action and Setter interfaces allow specifying simple behavior.
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);
}
};
For eg., if the textviews are grouped, you could do
例如,如果文本视图被分组,你可以做
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);
}
}
};
回答by Mark McClelland
If you want the children of a ViewGroup
to be unresponsive to touch events, but you want the ViewGroup
itself to respond to clicks, for example, you can create your own ViewGroup
subclass, override onInterceptTouchEvent()
, and always return true
. This will intercept all touch events before children see them, while allowing your custom ViewGroup
to remain responsive to touch events.
例如,如果您希望 a 的子类ViewGroup
对触摸事件无响应,但希望其ViewGroup
本身响应点击,则可以创建自己的ViewGroup
子类 overrideonInterceptTouchEvent()
并始终返回true
。这将在孩子们看到它们之前拦截所有触摸事件,同时允许您的自定义ViewGroup
保持对触摸事件的响应。
So, instead of RelativeLayout
, you could use your own subclass:
因此,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;
}
}
回答by Tamilselvan Kalimuthu
Since you are going to perform the click for some items in the layout when that particular function is executed,
由于您将在执行该特定功能时对布局中的某些项目执行单击,
- You can keep a static flag like a boolean
- Create a static boolean globally and declare it as
false
, once the particular function is performed change it totrue
. - so in all the onclick functions that u r performing check this flag if it is true perform the necessory function.
- 您可以像布尔值一样保留静态标志
- 全局创建一个静态布尔值并将其声明为
false
,一旦执行特定功能将其更改为true
. - 所以在你执行的所有 onclick 函数中,如果它是真的检查这个标志,执行必要的函数。
回答by CodeWarrior
You can make a common method in which you can write the code for disabling all your views inside your relative layout and call this method in onCreate()
and then you can enable your particular view inside the the layout on your event.
您可以创建一个通用方法,在该方法中您可以编写代码来禁用相对布局内的所有视图,并调用此方法onCreate()
,然后您可以在事件的布局内启用特定视图。
回答by Menna-Allah Sami
loop on your buttons and use setClickable function and pass false value for it. then when your even happen loop again on ot and setClickable to true
在您的按钮上循环并使用 setClickable 函数并为其传递 false 值。然后当你的偶数再次在 ot 上循环并且 setClickable 为 true 时