2011-01-06 17 views
4

私はクリック可能なカスタムTextViewを持っています。クリックに基づいて外観を変更するために、独自のonClickハンドラを定義します。しかし、私はクリックしたボタンに基づいて何かを行うために私のアクティビティで2番目のonClickハンドラを定義すると、onClick関数の1つだけが呼び出されます。 onClickはvoid関数です - 私はこのクリックを処理しなかったと言う方法はありますか?他のonClickハンドラに渡してください。私が持っているのTextViewを拡張Android - 2つのonClickリスナーと1つのボタン

インサイドMyCheckButton:ここより明確にする

はコードである

setOnClickListener(mClickListener); 

    private OnClickListener mClickListener = new OnClickListener() { 
     public void onClick(View v) { 
      toggle(); 
     } 
    }; 

私は私の活動にMyCheckButtonが含まれ、そしてもちろん私はときに何かをする必要がありしかし、

MyCheckButton button= (MyCheckButtonButton) findViewById(R.id.cb); 
button.setOnClickListener(new OnClickListener(){ 
    @Override 
    public void onClick(View v) { 
     // do something in the app 
    } 

}); 

setOnClickListenerを呼び出すことによって2回、私がTOGように、元のリスナーを交換していますことが表示されます:私はそれを別のOnClickListenerを添付してクリック外観を変更するgle()は決して呼び出されません。このボタンがクリックされたときに、その外観を変更するためにすでにonClickハンドラを使用している場合、私は自分のアクティビティで何かを行うことができますか?私は、両方のOnClickListenersが呼び出されるのを見ていると思いました。あなたは次のようにボタンにクリック時のリスナーを添付することができ

+0

ええ、私はあなたが正しいと思います。また、あなたのXMLファイルにonClick属性を与えて、onClickListenerを設定した後でもあなたのメソッドを呼び出すかどうかを調べることができます。 – schwiz

+0

私はこれがイベントのバブリングの問題ではないと思うし、私の問題は同じビューに2つのOnClickListenersを追加できないということですか?それは他の場所の標準的な練習なので、私は混乱しています。 – Mark

+0

xml onClickを使用すると、setOnClickListenerがそれをオーバーライドします。 – Mark

答えて

4

これは少し汚いですが、場合の方法は、私はこれを行うだろう複数のリスナーを必要とするのは、他のリスナーを知っているものを登録することです。最初に登録されたもの(実際に登録されているもの)は、イベントの条件に基づいて他のリスナーに委任する時期を知る必要があります。実際には、実際には2つのクラスを持つ必要はありません。 2番目のクラスは、必要なインターフェイスを実装できます。さらに、必要なものに対して特別なインターフェースを作成する必要はありません。

public class MyClickListener implements OnClickListener{ 
    private SomeCustomClass mSecondListener = new SomeCustomClass(); 
    public void onClick(View v){ 
    if (needToForward){ 
     mSecondListener.handleClick(v); 
    }else{ 
     //handle the click 
    } 
    } 
} 

次に、あなたの活動のためのあなたのコードでは、あなたがこの

MyClickListener lstn = new MyClickListener(); 
mCheckBox.setOnClickListener(lstn); 

を行うだろう、これはあなたのために動作しない理由はありますか?

また、2番目のクラスでは、OnClickListenerインターフェイスを実装することもできます。あなたは真の泡立ちが必要な場合

また、あなたはOnClickListenerインターフェイスを実装するために起こる中間クラスに複数のクリックリスナーを追加サポートし、独自のインタフェースを定義することができます。そこから、そのクラスのonClick()メソッドで、適切なメソッドを呼び出す登録されたリスナーを繰り返します。

+0

私は見ています、私はJavaの初心者ですので、すぐにわかりません。最後のオプションは、これがより頻繁に発生する場合に役立つ可能性があります。また、アプリケーションオブジェクトを使用してリスナーを登録することも検討しています。 – Mark

+0

ここでの最初の提案は、おそらく最もクリーンな最も単純な解決策です。 – Mark

-1

Button button= (Button) findViewById(R.id.button1); 
    button.setOnClickListener(new OnClickListener(){ 
     @Override 
     public void onClick(View v) { 
      // do something 
     } 

    }); 

と似て、あなたのTextViewには、クリック時のリスナー上にある必要があります。

+0

私の問題は2つのOnClickListenersと1つの 'ボタン'です。私のボタンは、私が拡張したTextViewです。 – Mark

+0

1つのビューで2つのclickListenersを持つことはできません。 – Falmarri

+0

私はなぜ他のすべてのUIシステムが複数のイベントハンドラをサポートしているのだろうか?なぜこの質問を 'イベントバブリング'とタグ付けするのですか? – Mark

1

ビューごとに1つのonClickListenerしか存在しないようです。私は私がしなければならないと思うと、インタフェースを定義している:

public interface MyOnClickListener { 
    public void onMyClick(View v); 
} 

私の活動から、それを実装し、私がやりたいためにonMyClick機能を無効にしてMyCheckButtonクラスで、私はコンストラクタでMyOnClickListenerに合格する必要がありますそれを保存して、onClickハンドラの中でlistener.onMyを呼び出します。

もっと良い方法を教えてください。私は、アクティビティまたはMyCheckButtonクラスのいずれかでonTouchハンドラを使用することを検討しましたが、後でonTouchまたはonClickをどちらかに追加すると、バグに気づくのが難しくなります。

私は私のコンストラクタから活動への参照を取得する方法がわからないので、私の考えは動作しません:

public class TVCheckButton extends TextView { 

    private MyOnClickListener mListener; 

    public TVCheckButton(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     mListener = ???; 
    } 
} 
+0

MyCheckButtonクラスに引数を追加する方法がわからない/私はxmlのMyCheckButtonビューをインスタンス化しています。 Context引数をアクティビティにキャストできますか? – Mark

1

Android 2.1でOnclickListenerが1つしか動作しないため(私はそれ以降のバージョンについてはわかりません)、ビューを非公開にして静的にし、静的な関数を作成します。

パブリッククラスExampleActivityアクティビティ{

private SomeOtherclass someOtherClass; 
private static Button b_replay; 

public void onCreate(Bundle savedInstanceState){ 
    someOtherClass = new SomeOtherclass(); 

    b_replay = (Button) findViewById(R.id.b_replay); 
    b_replay.setOnClickListener(someOtherClass); 
} 

public static void changeReplayText(String text){ 
    b_replay.setText(text); 
} 

}

2

よりクリーンなアプローチは、CompositeListenerパターンを使用することです。

から撮影

:あなたは、あなたのプロジェクトでこのクラスを追加する必要があると思います how can I set up multiple listeners for one event?

/** 
* Aux class to collect multiple click listeners. 
*/ 
class CompositeListener implements OnClickListener { 
    private List<OnClickListener> registeredListeners = new ArrayList<OnClickListener>(); 

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

    @Override 
    public void onClick(View v) { 

     for(OnClickListener listener:registeredListeners) { 
      listener.onClick(View v); 
     } 
    } 
} 

は、その後、あなたのMyCheckButton

private CompositeListener clickListener = new CompositeListener(); 

public MyCheckButton() 
{ 
    super.setOnClickListener(clickListener); //multi event listener initialization 
} 

@Override 
public void setOnClickListener(OnClickListener l) { 
    clickListener.registerListener(l); 
} 

どちらsetOnClickListenerにあなたの呼び出しでこれを追加このオーバーライドを経てリストに追加され、イベントが発生すると呼び出されます。それが役に立てば幸い。

0

何らかの理由で私は上の答えを使うことができませんでしたので、ここに代替えがあります: //私は2つのボタンがある1つの方法でこれをすべて持っていました。別名「なくなった」。だから、私はそれをチェックアウトした!誰かを助けることを願っています!

Button b = (Button) findViewById(R.id.b_reset); 
Button breakk = (Button) findViewById(R.id.b_break); 

    if ((findViewById(R.id.b_reset)).getVisibility() == View.VISIBLE) { 
     b.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

//いくつかのコードや方法...

  } 
     }); 
    } else if ((findViewById(R.id.b_break)).getVisibility() == View.VISIBLE) { 

     breakk.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

//いくつかのコードや方法...ファーストクラスで

  } 
     }); 
    } 
0

は、仮想ボタンを定義します。

private static Button myVirtualButton = new Button(context); 

...それを登録するパブリックメソッド:所望の、及び最終的に、仮想ボタンsoftclickれるどんなアクションOnClickListener

public static void registerMyVirtualButton(Button b) { myVirtualButton = b;} 

か:第二のクラスにおいて

if (myVirtualButton!=null) { myVirtualButton.callOnClick(); } 

を、さらにあるものは何でも動作とボタンとOnClickListenerを定義希望。

registerMyVirtualButtonでボタンをファーストクラスに送信します。 ファーストクラスのオブジェクトをクリックすると、両方のアクションが実行されます。

関連する問題