web-dev-qa-db-ja.com

android-マルチonClickリスナーを1つのボタンで

Mybutton.Javaのようなカスタムコンポーネントを作成し、Mybutton.Javaでonclickリスナーを設定しました。

今、私の新しいアクティビティでは、Mybuttonを呼び出して、onclickリスナーにコンテンツを追加する必要があります。

ただし、OnClickListener mClickListener = new OnClickListener(){......を使用すると、古いコンテンツが置き換えられます。新旧のリスナーが一緒にできることを願っています。

私はいくつかの情報を検索しましたが、このメソッドを実装できることがわかりました。何度も試行しても、まだエラーが発生します。

誰かが私にそれを変更することを学ぶことができる簡単な例を教えてもらえますか?

16
ctc8631

Android APIには複数のonClickリスナーを許可するAPIはないと思います。単一のonClick()を処理するカスタムクラスが必要です。呼び出すハンドラーを渡します。次のようなものです。

private class CompositeOnClickListener implements View.OnClickListener{
    List<View.OnClickListener> listeners;

    public CompositeOnClickListener(){
        listeners = new ArrayList<View.OnClickListener>();
    }

    public void addOnClickListener(View.OnClickListener listener){
        listeners.add(listener);
    }

    @Override
    public void onClick(View v){
       for(View.OnClickListener listener : listeners){
          listener.onClick(v);
       }
    }
}

ボタンを設定するときは、次のようにします。

CompositeOnClickListener groupListener = new CompositeOnClickListener();
myButton.setOnClickListener(groupListener);

次に、別のリスナーを追加するときはいつでも、

groupListener.addOnClickListener(new View.OnClickListener(){
   @Override
   public void onClick(View v){
      **** Custom implementation ****
   }
});
35
DeeV

次のようなカスタムButtonクラスを作成できます。

    public class MyButton extends Button {

    private CustomOnClickListener mCustomOnClickListener;

    public interface CustomOnClickListener {
        void onClick(View v);
    }


    public MyButton(Context context) {
        super(context);

        // Set your own onClickListener
        View.OnClickListener ocl = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Do whatever you want to do

                // Invoke the other added onclick listener
                if(mCustomOnClickListener != null) {
                    mCustomOnClickListener.onClick(v);
                }
            }
        };
        setOnClickListener(ocl);
    }

    // use this function to set the other onclick listener
    public void setCustomOnClickListener(CustomOnClickListener cl) {
        mCustomOnClickListener = cl;
    }

    }

そして、このように使用します:

    // create your button
    MyButton button = new MyButton(context);
    // add your custom onClickListener
    button.setCustomOnClickListener(new MyButton.CustomOnClickListener() {
        @Override
        public void onClick(View v) {
            // Do whatever you intend to do after the actual onClickListener
            // from MyButton class has been invoked.
        }
    });
4

カスタムビューのonClickで内部ロジックを実行し、外部で設定されたOnClickListenerのロジックを実行する場合は、次のようにsetOnClickListenerをオーバーライドするのが簡単な方法だと思います。

Kotlinの場合:

override fun setOnClickListener(externalOnClickListener: View.OnClickListener?) {
    val internalOnClickListener = View.OnClickListener { view -> 
        //Your awesome internal logic
        externalOnClickListener?.onClick(view)
    }
    super.setOnClickListener(internalOnClickListener)
}

Javaでも同じ:

@Override
public void setOnClickListener(@Nullable final View.OnClickListener externalOnClickListener) {
    View.OnClickListener internalOnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            //Your awesome internal logic
            if (externalOnClickListener != null) {
                externalOnClickListener.onClick(view);
            }
        }
    };
    super.setOnClickListener(internalOnClickListener);
}
2
mcspayne