Last active
March 19, 2017 02:27
-
-
Save ignaciotcrespo/365d3c476998884fd8aa321de5e2a47b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.CompoundButton; | |
import android.widget.RadioButton; | |
import android.widget.RadioGroup; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* {@link RadioGroup} supporting mutual exclusion in all {@link RadioButton} in the layout tree. | |
* For my friend Gryzor ;) | |
*/ | |
class DeepRadioGroup extends RadioGroup { | |
private List<RadioButton> radioButtons = new ArrayList<>(); | |
private OnCheckedChangeListener onCheckedChangeListener; | |
private OnHierarchyChangeListener onHierarchyChangeListener; | |
private CompoundButton.OnCheckedChangeListener radioButtonChangeListener; | |
public DeepRadioGroup(Context context) { | |
super(context); | |
init(); | |
} | |
public DeepRadioGroup(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
private void init() { | |
super.setOnHierarchyChangeListener(new HierarchyChangeListener(this)); | |
radioButtonChangeListener = new RadioButtonChangeListener(this); | |
} | |
private void addRadioButton(RadioButton button) { | |
radioButtons.add(button); | |
button.setOnCheckedChangeListener(radioButtonChangeListener); | |
} | |
private void removeRadioButton(RadioButton child) { | |
radioButtons.remove(child); | |
} | |
@Override | |
public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { | |
onHierarchyChangeListener = listener; | |
} | |
private void delegateOnChildViewAdded(View parent, View child) { | |
if (onHierarchyChangeListener != null) { | |
onHierarchyChangeListener.onChildViewAdded(parent, child); | |
} | |
} | |
private void delegateOnChildViewRemoved(View parent, View child) { | |
if (onHierarchyChangeListener != null) { | |
onHierarchyChangeListener.onChildViewRemoved(parent, child); | |
} | |
} | |
@Override | |
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { | |
super.setOnCheckedChangeListener(listener); | |
this.onCheckedChangeListener = listener; | |
} | |
private void triggerMutualExclusion(CompoundButton checked) { | |
super.setOnCheckedChangeListener(null); | |
for (RadioButton button : radioButtons) { | |
if (button != checked) { | |
button.setChecked(false); | |
} | |
} | |
super.setOnCheckedChangeListener(onCheckedChangeListener); | |
} | |
private static class RadioButtonChangeListener implements CompoundButton.OnCheckedChangeListener { | |
private DeepRadioGroup group; | |
private RadioButtonChangeListener(DeepRadioGroup group) { | |
this.group = group; | |
} | |
@Override | |
public void onCheckedChanged(CompoundButton button, boolean isChecked) { | |
if (isChecked) { | |
group.triggerMutualExclusion(button); | |
} | |
} | |
} | |
@SuppressWarnings("StatementWithEmptyBody") | |
private static class HierarchyChangeListener implements OnHierarchyChangeListener { | |
private DeepRadioGroup group; | |
private HierarchyChangeListener(DeepRadioGroup group) { | |
this.group = group; | |
} | |
@Override | |
public void onChildViewAdded(View parent, View child) { | |
if (child instanceof RadioGroup) { | |
// ignore nested groups | |
} else if (child instanceof RadioButton) { | |
group.addRadioButton((RadioButton) child); | |
} else if (child instanceof ViewGroup) { | |
ViewGroup group = (ViewGroup) child; | |
for (int i = 0; i < group.getChildCount(); i++) { | |
onChildViewAdded(child, group.getChildAt(i)); | |
} | |
} | |
group.delegateOnChildViewAdded(parent, child); | |
} | |
@Override | |
public void onChildViewRemoved(View parent, View child) { | |
if (child instanceof RadioGroup) { | |
// ignore nested groups | |
} else if (child instanceof RadioButton) { | |
group.removeRadioButton((RadioButton) child); | |
} else if (child instanceof ViewGroup) { | |
ViewGroup group = (ViewGroup) child; | |
for (int i = 0; i < group.getChildCount(); i++) { | |
onChildViewRemoved(child, group.getChildAt(i)); | |
} | |
} | |
group.delegateOnChildViewRemoved(parent, child); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment