For example I have:
Although not quite the same as disabling views within a layout, it is worth mentioning that you can prevent all children from receiving touches (without having to recurse the layout hierarchy) by overriding the ViewGroup#onInterceptTouchEvent(MotionEvent) method:
public class InterceptTouchEventFrameLayout extends FrameLayout {
private boolean interceptTouchEvents;
// ...
public void setInterceptTouchEvents(boolean interceptTouchEvents) {
this.interceptTouchEvents = interceptTouchEvents;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return interceptTouchEvents || super.onInterceptTouchEvent(ev);
}
}
Then you can prevent children from receiving touch events:
InterceptTouchEventFrameLayout layout = (InterceptTouchEventFrameLayout) findViewById(R.id.layout);
layout.setInterceptTouchEvents(true);
If you have a click listener set on layout
, it will still be triggered.
private void disableLL(ViewGroup layout){
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
child.setClickable(false);
if (child instanceof ViewGroup)
disableLL((ViewGroup) child);
}
}
and call method like this :
RelativeLayout rl_root = (RelativeLayout) findViewById(R.id.rl_root);
disableLL(rl_root);
I personally use something like this (vertical tree traversal using recursion)
fun ViewGroup.deepForEach(function: View.() -> Unit) {
this.forEach { child ->
child.function()
if (child is ViewGroup) {
child.deepForEach(function)
}
}
}
usage :
viewGroup.deepForEach { isEnabled = false }
I improved the tütü response to properly disable EditText and RadioButton componentes. Besides, I'm sharing a way that I found to change the view visibility and add transparency in the disabled views.
private static void disableEnableControls(ViewGroup view, boolean enable){
for (int i = 0; i < view.getChildCount(); i++) {
View child = view.getChildAt(i);
child.setEnabled(enable);
if (child instanceof ViewGroup){
disableEnableControls((ViewGroup)child, enable);
}
else if (child instanceof EditText) {
EditText editText = (EditText) child;
editText.setEnabled(enable);
editText.setFocusable(enable);
editText.setFocusableInTouchMode(enable);
}
else if (child instanceof RadioButton) {
RadioButton radioButton = (RadioButton) child;
radioButton.setEnabled(enable);
radioButton.setFocusable(enable);
radioButton.setFocusableInTouchMode(enable);
}
}
}
public static void setLayoutEnabled(ViewGroup view, boolean enable) {
disableEnableControls(view, enable);
view.setEnabled(enable);
view.setAlpha(enable? 1f: 0.3f);
}
public static void setLayoutEnabled(ViewGroup view, boolean enable, boolean visibility) {
disableEnableControls(view, enable);
view.setEnabled(enable);
view.setAlpha(enable? 1f: 0.3f);
view.setVisibility(visibility? View.VISIBLE: View.GONE);
}
this one is recursive for ViewGroups
private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
View child = vg.getChildAt(i);
child.setEnabled(enable);
if (child instanceof ViewGroup){
disableEnableControls(enable, (ViewGroup)child);
}
}
}
tutu's answer is on the right track, but his recursion is a little awkward. I think this is cleaner:
private static void setViewAndChildrenEnabled(View view, boolean enabled) {
view.setEnabled(enabled);
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
setViewAndChildrenEnabled(child, enabled);
}
}
}