EventMultiCaster
以前にも書いたが、Android SDKの一般的なビューはイベントハンドラがシングルキャストであり、複数のリスナを登録することができない。
暫く放置していたのだが、やはりマルチキャストに対応しなければならない要件が出てきたのでそのためのクラスを作ってみた。
- IListenerMulticaster.java
public interface IListenerMulticaster{ IListenerMulticaster pushListener(L l); L popListener(); void removeListener(L l); int size(); }
IListenerMulticasterはEventLisatenerの代わりに使うインタフェース。
pushListenerはaddListenerの方が分かり易いかもしれない。
- AbstractListenerMulticaster.java
public abstract class AbstractListenerMulticasterimplements IListenerMulticaster { protected Stack listeners; public AbstractListenerMulticaster() { super(); this.listeners = new Stack (); } @Override public IListenerMulticaster pushListener(L l) { if ( l != null ) { this.listeners.push(l); } return this; } @Override public L popListener() { return this.listeners.pop(); } @Override public void removeListener(L l) { this.listeners.remove(l); } @Override public int size() { return this.listeners.size(); } }
Androidの場合イベントリスナの型階層が無いため(残念だ)、具象クラスはイベントリスナの型毎に用意しなくてはならない。
例えば、クリックイベントのためのリスナをマルチキャストにするためのクラスは、上記のテンプレートから継承して以下のように実装する。
- ClickListenerMulticaster.java
public class ClickListenerMulticaster extends AbstractListenerMulticasterimplements OnClickListener { @Override public void onClick(View v) { for ( OnClickListener l : this.listeners ) { l.onClick(v); } } }
実際には以下のように使う。
- HogeActivity.java
@Override public void onCreate(Bundle savedInstanceState) { Button button = (Button)this.findViewById(R.id.Button01); ClickListenerMulticaster caster = new ClickListenerMulticaster(); caster.pushListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(Addressdroid.this, "I am listener 1", Toast.LENGTH_SHORT).show(); }}); caster.pushListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(Addressdroid.this, "I am listener 2", Toast.LENGTH_SHORT).show(); }}); caster.pushListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(Addressdroid.this, "I am listener 3", Toast.LENGTH_SHORT).show(); }}); button.setOnClickListener(caster); }
実行するとボタンクリック時、トーストに
[I am listener 1]
[I am listener 2]
[I am listener 3]
と順に表示される。
思いつきでいきなり書いたので、バグはあるかもしれない。ご容赦。
追記:
やはり、イベントリスナの型毎に具象クラスを起こすのが面倒だな。あと、せっかくIListenerMulticaster
01| IListenerMulticastercaster = new ClickListenerMulticaster(); 02| button.setOnClickListener(caster);
という書き方ができない(02行目がエラー)のも恰好がよくないな。