29

I want to set up multiple listeners for one event, and have found that using composite listener is the key.

Could anyone give me an example?

Vicky
  • 1,379
  • 6
  • 18
  • 29

3 Answers3

55
class CompositeListener implements OnEventListener {
   private List<OnEventListener> registeredListeners = new ArrayList<OnEventListener>();

   public void registerListener (OnEventListener listener) {
      registeredListeners.add(listener);
   }

   public void onEvent(Event e) {
      for(OnEventListener listener:registeredListeners) {
         listener.onEvent(e);
      }
   }
}

.....

CompositeListener composite = new CompositeListener();
composite.registerListener(listener1);
composite.registerListener(listener2);
component.setOnEventListener(composite);
Flavio
  • 6,205
  • 4
  • 30
  • 28
5

you can try this hack you will need to extend the view e.g. extend the Button to accept multiple onclick listeners. you create an inner class that implements OnclickListener

private class OnclickListenerCollection implements OnClickListener{
    private ArrayList<OnClickListener> listeners;

    public void addOnclickListener(OnClickListener listener){
        listeners.add(listener);
    }

    @Override
    public void onClick(View v) {
        for(OnClickListener l : listeners){
            l.onClick(v);
        }

    }
}

in the constructor of you sub-classed button, you call super.setOnclickListener passing an instance of you inner class

private OnclickListenerCollection listenerCollector;

in your constructor you have:

listenerCollector = new OnclickListenerCollection();
super.setOnClickListener(listenerCollector);

you override the setOnclickListener method to add listeners to the collection

@Override
public void setOnClickListener(OnClickListener l) {

    listenerCollector.addOnclickListener(l);
}

i have not tried it but i believe it will work

araoko
  • 93
  • 2
  • 6
  • 6
    I wouldn't call this a hack. – ingh.am Nov 04 '13 at 15:46
  • It is a good idea. IMHO, it can be improved with one small change. As described, it alters the meaning of `setOnClickListener`. The meaning would be clearer if instead implement two methods whose names say what they do: `addOnClickListener` and `removeOnClickListener`. – ToolmakerSteve Oct 20 '16 at 19:20
1

I know it is several years late, but wanted to add my version that I just spent a few hours getting to work. Here is the code located in the file DBupdateEventListener.java:

public interface DBupdateEventListener {
    public void onUpdateChannelSubscriptions();
}
class DBupdateEventListenerRegistry implements DBupdateEventListener{
    public static List<DBupdateEventListener> registeredListeners = new ArrayList<DBupdateEventListener>();
    public void registerListener(DBupdateEventListener listener){
        registeredListeners.add(listener);
    }
    public void onUpdateChannelSubscriptions(){
        for (DBupdateEventListener listener:registeredListeners){
            listener.onUpdateChannelSubscriptions();
        }
    }
}

it is very VERY important that registeredListeners is a public static variable. This is the whole reason that I added my own answer to this question several years after it had already been closed.

and here is the code I use in the OnCreate() method of the fragment that needs to be updated after the event is triggered:

        dbUpdater = new DBupdateEventListener() {
            @Override
            public void onUpdateChannelSubscriptions() {
                //put the code you want to run when the event is triggered here:
                loadChannelListsFromDB();
            }
        };
        DBupdateEventListenerRegistry temp = new DBupdateEventListenerRegistry();
        temp.registerListener(dbUpdater);

and here is the code used in my asynchronous task that triggers the event in the first place:

dbUpdaterRegistry = new DBupdateEventListenerRegistry();
dbUpdaterRegistry.onUpdateChannelSubscriptions();
Joe Ryan
  • 93
  • 1
  • 1
  • 6
  • `registeredListeners` only needs to be `static` if it isn't a field on an object that is already known to be staying around for as long as is needed. One downside of `static` is that now it will stay around for as long as your app is alive. While sometimes that is good, it isn't a "recipe" that you want to be in the habit of using. A second downside of `static` is that now you can't create **two instances** of the class, each with their own set of listeners. Instead, in an activity/fragment, have a **field** `DBupdateEventListenerRegistry eventRegistry;`, for the listeners of that activity. – ToolmakerSteve Oct 20 '16 at 19:37