Reputation: 35141
Looking through the Android View code (specifically at RadioButton and RadioGroup), I see that both classes only allow one Listener at a time (externally provided -- they have their own internal listeners too). Setting a second Listener just overwrites:
E.g., in RadioGroup:
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
mOnCheckedChangeListener = listener;
}
I'd assumed a set of Listeners would be kept (or chained), and iterated through on an event broadcast. Instead, whichever listener is last set "wins". That seems fragile.
What's the rationale for this?
Upvotes: 0
Views: 116
Reputation: 36289
This is primarily done to handle things like UI layering. For example you might have the background, with View A
on top of it that handles clicks - but You show View B
above A
when the user clicks a button. Now if you click B
, you don't want A
to respond. It's meant as a simplification.
As stated in the comments, certain events can return false
after handling a click, for example, so that the next layer can handle the event.
If you do create a reference to all of the Objects waiting to hear from a click event, you can use an ordered data structure, such as an ArrayList
, to ensure that the order an event is handled is not random.
For example, start with an interface that has a method that returns true
or false
. OnCheckedChange
does not do this (moved the d
's:
public interface OnCheckChangedListener {
public boolean onCheckChanged(CompoundButton buttonView, boolean isChecked)
}
Now create a subclass of RadioGroup
with the following global variable:
private List<OnCheckChangedListener> listeners = new ArrayList<OnCheckChangedListener>();
Then have the methods:
public void addOnCheckChangedListener(OnCheckChangedListener listener) {
this.listeners.add(listener);
}
public void removeOnCheckChangedListener(OnCheckChangedListener listener) {
this.listeners.remove(listener);
}
Then in your constructor, just add this:
this.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChange(CompoundButton buttonView, boolean isChecked) {
for (int i = 0; i < listeners.size(); i++) {
if (listeners.get(i).onCheckChanged(buttonView, isChecked))
break;
}
}
});
Now all of the listeners will have a chance to respond, but the order will be handled like onClick
or onTouch
. You can also not call break
, and just let all the listeners get called (in order).
Upvotes: 1