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.
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
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
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:
mMask.setVisibility(View.VISIBLE); // blocks children
mMask.setVisibility(View.GONE); // children clickable
An easy Kotlin extension solution to disable/enable a view and all of it's children:
fun View.isUserInteractionEnabled(enabled: Boolean) {
isEnabled = enabled
if (this is ViewGroup && this.childCount > 0) {
this.children.forEach {
it.isUserInteractionEnabled(enabled)
}
}
}
and call it with:
view.isUserInteractionEnabled(false)
Since you are going to perform the click for some items in the layout when that particular function is executed,
false
, once the particular function is performed change it to true
.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.
So, instead of RelativeLayout
, you could use your own subclass:
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;
}
}
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.