2016-05-03 13 views
4

クリック可能なビュー(例えばボタン)にonClickListenerを追加するには、次の4つの方法があります。アンドロイドonClickListenerの実装のベストプラクティス

  1. は、活動の方法を指すレイアウトファイル内のonClick属性を設定し、
  2. プライベートメンバ変数にonClickListenerを割り当てる
  3. 、匿名の内部クラスを作成します。
  4. には、onClickListenerインターフェイスを実装するアクティビティコンテキストがあります。

私の質問は、どのようにこれらの実装方法の1つを別の方法で選択するかです。特定の条件に基づいてベストプラクティスが存在するのでしょうか、それとも単にプログラマーの好みの問題ですか?

+1

匿名の内部クラスは危険で、外部クラスを漏洩する可能性があるため、このパターンは避けてください。私は、参照が必要な場合は外部クラスへのWeakReferenceを持つ静的内部クラスを使用するか、またはアクティビティ自体をonClickListenerにすることをお勧めします。 –

+0

メンバー変数のオプションも避けてください。もしそうなら、なぜですか?ありがとう! – JaeW

+0

onClickListenerへの参照を保持するメンバ変数の場合は、onClickメソッドを実装するために宣言されたクラスが必要になります。したがって、外部クラスのスコープ内で宣言されている場合は静的であることを確認し、外部クラス(内部クラスまたは別のクラスとして宣言されているかどうかに関係なく外部クラスへの参照が必要な場合は、 elseshwereと宣言した)それは弱い参照である。 –

答えて

4

ここでは、いわゆるコールバックパターンを使用します。

public class Button { 
    private Callback callback; 

    public Button(Callback callback) { 
     this.callback = callback; 
    } 

    public void update() { 
     // Check if clicked.. 
     callback.onClick(this); 
    } 

    public interface Callback { 
     public void onClick(Button Button); 
    } 
} 


Button b = new Button(new Callback() { 
    @Override 
    public void onClick(Button b) { 
     System.out.println("Clicked"); 
    } 
}); 

このケースでは、onClickハンドラは、インターフェイスView.OnClickListenerを実装しています。

キーポイント:活性/断片と

  • 一貫。
  • activity/fragmentのメンバーへのアクセス。
  • 可読性;
  • @Michaelクラウスmemory leaksについてのもう一つの良い点を示しました。 @Karakuriは、それが遅いリフレクションを使用したように、XMLファイル内

1)属性は、唯一の活性のために使用することができます。

2)匿名の内部クラスには、囲むクラスのメンバーへのアクセスに特別なルールがあります(チェック[1][2])。メモリリークが発生する場合があります(例:AsyncTask、Handlersを使用したスレッド化)。

3)ここでは、クラスを囲むのメンバーへのフルアクセスを持っています。

4)3Dのバリエーションです。

可読性があなたのハンドラのサイズによって異なり、小さなロジックはインラインに、コードの大きなブロックのために[OK]をすることができ、3Dと第四考えます。それは、特定のアクティビティにレイアウトを結びつけるよう

+0

Androidでは、インターフェイスはすでにonClickListener()の形式で作成されています。上記のコードとは対照的に、Androidボタンが実装されている場合、onClickListener()をパラメータとして受け入れる(既存の)コンストラクタはありません。代わりに、Viewクラスから継承するsetOnClickListener()を使用する必要があります。これはすべて正しいですか? – JaeW

+0

例は、コールバックパターンの考え方のみを示しています。 Android APIでは、インターフェース[View.OnClickListener](https://developer.android.com/reference/android/view/View.OnClickListener.html)が必要な 'setOnClickListener()'のようなsetメソッドを使用します。 BTWと同じコンセプトは、Fragmentとホストアクティビティ([example](https://developer.android.com/training/basics/fragments/communicating.html))との間のチャットにお勧めします。 –

2

私は(それが反射を介した方法を見つけなければならない)onClick属性を使用することはありません。フラグメント上では機能しません。

オプション2および3は、実質的に同一です。プライベートメンバーを複数ビューのOnClickListenerとして使用する場合は、オプション3を使用する方が効果的です。

オプション4はオプション3に近いです。主な違いの1つはクラス宣言を変更することです。クラス宣言にインターフェイス実装がないようにすることが重要な場合(または、ある種のバイナリ互換性を維持する必要がある)、このオプションを使用したくない場合があります。

私のアドバイスは、オプション1を避けて、あなたのコードスタイルに最も適したものを選択することです。また、コード内のすべての場所で同じアプローチを使用する必要はありません。

+0

ありがとうございます。非常に役立ちます。その他の質問:クラス宣言にインターフェイス実装がないようにしたいのはなぜですか? – JaeW

+0

@ JaeW一例として、そのクラスの以前のバージョンとのバイナリ互換性を維持することができます(おそらくこれが何らかの種類のSDKにある場合)。また、クラスがインターフェイスを実装するようにする場合、そのインターフェイスが予期せずどこでも使用できる誰でも、それを可能にしたくない場合もあります。 – Karakuri

関連する問題