Вы можете использовать динамические прокси Java для решения этой проблемы:
public class MultiListenerExample {
private ArrayList<OnClickListener> onClickListeners = new ArrayList<OnClickListener>(); private OnClickListener dispatcher;
public void performOnClick(View v) {
dispatch().onClick(v);
}
private OnClickListener dispatch() {
if (dispatcher == null) {
dispatcher = createDispatcher();
}
return dispatcher;
}
private OnClickListener createDispatcher() {
ClassLoader loader = OnClickListener.class.getClassLoader();
Class<?>[] interfaces = new Class[] { OnClickListener.class };
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
for (OnClickListener listener : onClickListeners) {
// safe to call this since we implement the same interface as the object of the original invocation
method.invoke(listener, args);
}
return null;
}
};
return (OnClickListener) Proxy.newProxyInstance(loader, intefaces, handler);
}
}
Каждый вызов интерфейса, возвращаемый dispatch()
, будет распространяться в объект InvocationHandler
, который реализован таким образом, что он будет проходить через контейнер слушателей и выполнять исходный вызов для каждого элемента .
Метод можно безопасно вызывать, поскольку исходный вызов был выполнен на том же интерфейсе, который мы собираемся вызвать.
Это решение может работать, если у ваших слушателей нет возвращаемого значения.