Android - Two onClick listeners and one button

user317033 picture user317033 · Jan 6, 2011 · Viewed 22.8k times · Source

I have a custom TextView which is clickable. It defines its own onClick handler in order to change its appearance based on clicks. However if I then define a second onClick handler in my activity in order to do something based on the button being clicked, only one of the onClick functions is called. onClick is a void function - is there any way to say I didn't process this click, please pass it on to other onClick handlers?

To be more clear here is the code:

Inside MyCheckButton which extends TextView I have:

    setOnClickListener( mClickListener );

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

However I include MyCheckButton into my Activity, and of course I need to do something when its clicked so I attach another OnClickListener to it:

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

});

By calling setOnClickListener twice it appears that I am replacing the original listener so toggle() which changes the appearance is never called. How can I do something in my activity when this button is clicked if it is already using the onClick handler to change its appearance? I thought I would simply see both OnClickListeners getting called.

Answer

Chris Thompson picture Chris Thompson · Jan 7, 2011

This is a bit dirty, but the way I would do this if you need multiple listeners is to register one that knows about the other. The first one (the one that's actually registered) will then need to know when to delegate to the other listener based on the conditions of the event. Actually, in reality, there's no real need to have two OnClickListener classes. The second class can implement whatever interface you want. Additionally, there's no need to create a special interface for what you need.

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

Then, in your code for your activity, you would do this

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

Is there a reason this wouldn't work for you?

Alternatively, if you wanted, the second class could also implement the OnClickListener interface.

Additionally, if you need true bubbling, you could define your own interface that supports adding multiple click listeners to an intermediate class that happens to implement the OnClickListener interface. From there, in that class's onClick() method, you would iterate through the registered listeners calling the appropriate method.