5

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

より明確にするために、コードは次のとおりです。

TextView を拡張する MyCheckButton の内部には、次のものがあります。

    setOnClickListener( mClickListener );

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

ただし、MyCheckButton をアクティビティに含めます。もちろん、クリックされたときに何かを実行する必要があるため、別の OnClickListener をアタッチします。

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

});

setOnClickListener を 2 回呼び出すと、元のリスナーを置き換えているように見えるため、外観を変更する toggle() は呼び出されません。既に onClick ハンドラーを使用して外観を変更している場合、このボタンがクリックされたときにアクティビティで何かを行うにはどうすればよいですか? 両方の OnClickListeners が呼び出されるのを見るだけだと思いました。

4

8 に答える 8

7

これは少し汚いですが、複数のリスナーが必要な場合にこれを行う方法は、もう一方を知っている一方を登録することです。最初のリスナー(実際に登録されているもの)は、イベントの状態に基づいて、他のリスナーにいつ委任するかを知る必要があります。実際には、実際には2つのOnClickListenerクラスを持つ必要はありません。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()メソッドで、適切なメソッドを呼び出す登録済みリスナーを反復処理します。

于 2011-01-06T23:33:14.177 に答える
1

Android 2.1 では OnclickListener が 1 つしか機能しないため [以降のバージョンについてはわかりません] ビューをプライベートかつ静的にし、それを変更できる静的関数を作成します。

public class ExampleActivity extends Activity{

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);
 }

}

于 2012-01-25T11:34:41.027 に答える
1

表示されているので、ビューごとに onClickListener を 1 つしか持てません。私がしなければならないと思うのは、インターフェースを定義することです:

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

アクティビティから実装し、onMyClick 関数をオーバーライドして、必要なことを行います。MyCheckButton クラスでは、コンストラクターに MyOnClickListener を渡して保存し、onClick ハンドラー内で listener.onMyClick を呼び出す必要があります。

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

コンストラクターからアクティビティへの参照を取得する方法がわからないため、私のアイデアは機能しません。

public class TVCheckButton extends TextView {

    private MyOnClickListener mListener;

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

        mListener = ???;
    }
}
于 2011-01-06T20:54:55.627 に答える
0

最初のクラスで、仮想ボタンを定義します。

private static Button myVirtualButton = new Button(context);

...そしてそれを登録するパブリックメソッド:

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

必要な操作を行いOnClickListener、最後に仮想ボタンをソフトクリックします。

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

2 番目のクラスでは、ボタンを定義し、OnClickListener追加で必要なアクションを指定します。

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

于 2017-12-20T15:14:04.230 に答える
0

優れた一般的なアプローチは、Beryl ライブラリのListenerListWeakListenerListなどのリスナーのリストを使用することです。

于 2012-04-24T08:39:43.610 に答える
-3

次の方法で、OnClick リスナーをボタンにアタッチできます。

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

    });

同様に、TextView には OnClick リスナーが必要です。

于 2011-01-06T19:33:10.440 に答える