Dynamically add features to Button onclicklistener Android

Purpose: I am looking for a way to add functionality to the onClickListener button.

Illustration

Button trigger = new Button(getActivity()); trigger.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { method1(); } }); Button runMethod2Button = new Button(getActivity()); runMethod2Button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { method1(); method2(); } }); Button runMethod3Button = new Button(getActivity()); runMethod3Button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { method1(); method3(); method4(); } }); 

I know that we can do this with inheritance by calling

 @Override public void method(){ super.method(); // Do appended stuff } 

Or we can do it inline

 new Object(){ @Override public void method(){ super(); // Do appended stuff } } 

Things i tried

Button extension to contain a list of Runnable Objects. Then set the on-click listener to run all running objects.

Is there any other / more efficient way to do this?

+5
source share
3 answers

Since we don’t know much about why you want to do this, it’s hard to do what is best. If you want the original listener to remain intact / untouched, you can use a decorator / wrapper template.

Wikipedia Drawing Decorator

In the specific case, this means that it is quite comparable to your Runnable approach, but you are not dependent on another interface. Everthing is handled through View.OnClickListener , which has the following advantages:

  • This is a general approach by which you can even “expand” listeners that you don’t have access to the source or that you don’t want to change.
  • You can create extension behavior at runtime, and you can extend already created instances (as opposed to using inheritance)
  • Extensions do not need to know that they are extensions, they are just normal OnClickListeners . In your approach, Runnable extensions are "special" and, for example, they do not receive the View parameter of the onClick method.

     public class OriginalOnClickListener implements View.OnClickListener{ @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"Original Click Listener",Toast.LENGTH_LONG).show(); } } public class ExtensionOnClickListener implements View.OnClickListener{ @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"Extension Click Listener",Toast.LENGTH_LONG).show(); } } public class DecoratorOnClickListener implements View.OnClickListener { private final List<View.OnClickListener> listeners = new ArrayList<>(); public void add(View.OnClickListener l) { listeners.add(l); } @Override public void onClick(View v) { for(View.OnClickListener l : listeners){ l.onClick(v); } } } 

And this is something like this:

  DecoratorOnClickListener dl = new DecoratorOnClickListener(); dl.add(new OriginalOnClickListener()); dl.add(new ExtensionOnClickListener()); editText.setOnClickListener(dl); 
+4
source

I think the Runnable idea is ok based on what you said here. Since I don't know why you need dynamic click handlers, I think a possible solution would look something like this:

 private class DynamicOnClickListener implements View.OnClickListener { private final List<Runnable> mRunnables = new ArrayList<>(); public void add(Runnable r) { mRunnables.add(r); } @Override public void onClick(View v) { for (Runnable r : mRunnables) { r.run(); } } } 

And you will use it as follows:

  DynamicOnClickListener listener = new DynamicOnClickListener(); listener.add(new Runnable() { @Override public void run() { doSomething(); } }); listener.add(new Runnable() { @Override public void run() { doSomethingElse(); } }); mButton.setOnClickListener(listener); 
+1
source

what about something like

  Button trigger = new Button(getActivity()); trigger.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { method1(); if (someVar) method2(); if (someVar2) method3(); } }) 
0
source

All Articles