Android - two onClick listeners and one button

I have a custom TextView that can be clicked. He defines his own onClick handler to change its look based on clicks. However, if I then define a second onClick handler in my activity to do something based on the click of a button, only one of the onClick functions is called. onClick is a void function - is there a way to say that I did not handle this click, please pass it on to other onClick handlers?

More clear is the code:

Inside MyCheckButton, which extends TextView, I:

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

However, I include MyCheckButton in my activity, and, of course, I need to do something when it is 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 seems like I'm replacing the original listener so that toggle () changes the look that is never called. How can I do something in my activity when this button is pressed, if it already uses the onClick handler to change its appearance? I thought I would just see how OnClickListeners would be called.

+4
source share
8 answers

It's a bit dirty, but the way I would do this if you need a few listeners is to register one that knows about the other. The first (the one that is actually registered), then must know when to delegate to another listener, depending on the conditions of the event. In fact, there is really no need to have two OnClickListener classes. The second class can implement any interface you want. In addition, there is 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 will do it

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

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

Alternatively, if you want, the second class can also implement the OnClickListener interface.

In addition, if you need real bubbling, you can define your own interface that supports the addition of several click listeners to an intermediate class that implements the OnClickListener interface. From there, in the onClick() method of this class, you will go through registered listeners by calling the corresponding method.

+4
source

A cleaner approach would be to use the CompositeListener pattern.

Taken from: how to configure multiple listeners for a single event?

You need to add this class to your project:

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

Then add this to your MyCheckButton

 private CompositeListener clickListener = new CompositeListener(); public MyCheckButton() { super.setOnClickListener(clickListener); //multi event listener initialization } @Override public void setOnClickListener(OnClickListener l) { clickListener.registerListener(l); } 

Both of your calls to setOnClickListener will go through this redefinition, add to the list, and trigger when the event setOnClickListener . Hope this helps.

+2
source

Since it appears, I can only have one onClickListener for each view. It seems to me that I need to define an interface:

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

Deploy it from my activity and override the onMyClick function to do whatever I want, and in the MyCheckButton class I need to pass MyOnClickListener in the constructor, save it and call listener.onMyClick inside the onClick handler.

Let me know if this is the best. I considered using the onTouch handler in an activity or MyCheckButton class, but later, if I add onTouch or onClick to one, it will be difficult for me to notice an error.

My idea does not work, because I do not know how to get the link to the activity from my constructor:

 public class TVCheckButton extends TextView { private MyOnClickListener mListener; public TVCheckButton(Context context, AttributeSet attrs) { super(context, attrs); mListener = ???; } } 
+1
source

Since only one OnclickListener works on Android 2.1 [I don't know about later versions), make the view private and static and create a static function that can change it, for example.

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

}

+1
source

A good general approach is to use a list of listeners such as the ListenerList and WeakListenerList from the Beryl library .

0
source

For some reason, I couldn’t use the answers above, so here’s the alternative: // I had it all in one method, where I had two buttons, and based on external factors, I could see it and others couldn’t leave. " So, I had it checked! Hope this helps someone!

 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) { 

// some code and methods ...

  } }); } else if ((findViewById(R.id.b_break)).getVisibility() == View.VISIBLE) { breakk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { 

// some code and methods ...

  } }); } 
0
source

In the first class, define a virtual button:

 private static Button myVirtualButton = new Button(context); 

... and the public registration method:

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

In OnClickListener perform any action, and at the end, click the softclick virtual button:

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

In the second class, define a button and its OnClickListener with any desired action.

Pass the button to the first class through registerMyVirtualButton . When you click on an object of the first class, both actions will be performed.

0
source

You can connect the OnClick listener to the button as follows:

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

Similarly, your TextView should have it on an OnClick listener.

-1
source

Source: https://habr.com/ru/post/1334556/


All Articles