67

How can i pass parameter to an OnClickListener() ?

Got my Listener:

   OnClickListener myListener = new OnClickListener()
   {

     @Override
     public void onClick(View v)
     {
         //I want to reach params here

     }

  };

I got 12 buttons and i dont want to write 12 listeners for them, it would be great to just pass a string to them and they can do completly different things.

Adam Varhegyi
  • 11,307
  • 33
  • 124
  • 222

9 Answers9

160

Use your own custom OnClickListener

public class MyLovelyOnClickListener implements OnClickListener
   {

     int myLovelyVariable;
     public MyLovelyOnClickListener(int myLovelyVariable) {
          this.myLovelyVariable = myLovelyVariable;
     }

     @Override
     public void onClick(View v)
     {
         //read your lovely variable
     }

  };
Sherif elKhatib
  • 45,786
  • 16
  • 89
  • 106
  • 1
    Is there any advantage for this method over using a member variable and then assigning the value to it and accessing it inside the onClick? If yes what? – Sreekanth Karumanaghat Nov 17 '16 at 05:48
  • This answers the question though it also makes it obvious that the Listener should have been designed as a method not a full blown class. It would be so much simpler to pass anonymous method with custom args (e.g. View v) – Andrej K Jan 05 '17 at 01:52
  • 1
    this is the most clean, readable and easy to maintain solution. The advantage of the members inside - clearly indicates what the onClick method needs to work properly and enforce you to pass correct arguments when assigning it to a button. Don't forget you can use javadoc to describe the purpose of this particular listener and reuse it if you need it. – mihail Feb 14 '17 at 09:38
30

Another solution for that issue, you can create a regular method and pass to it the View you want to add the onClickListener to it, and pass the parameters you want to use along with it:

Button b1 = new Button();
String something = "something";
Button b2 = new Button();
String anotherSomething = "anotherSomething";
setOnClick(b1, something);
setOnClick(b2, anotherSomething);

private void setOnClick(final Button btn, final String str){
    btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                  // Do whatever you want(str can be used here)

           }
    });
}
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Muhammed Refaat
  • 8,914
  • 14
  • 83
  • 118
9

I know this is a late answer but hopefully it can help someone. None of the existing answers worked in my situation but I ended up using the setTag feature of an image that was acting like a button. My account info was in a global member variable that was set up when the activity started.

In this case I am setting up a table with each row being an account. The account details are shown when the image is clicked (the image is just an info icon).
Thus:

// prior code....
// NOTE: oneAccount is an object (AccountInfo) holding information about the account

// column with the "detail" arrow
image1 = new ImageView(this);
image1.setImageResource(R.drawable.info);
image1.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
image1.setPadding(15, 1, 15, 1);
image1.setTag(oneAccount);
// add a listener to go to that account detail on a click
image1.setOnClickListener(new TextView.OnClickListener() {
    public void onClick(View v) {
    // change the color to signify a click
    v.setBackgroundColor(getResources().getColor(R.color.button_selected));


    // get what we need out of the tag
    AccountInfo thisAcct = (AccountInfo) v.getTag();

        // your code would do other stuff here

}
});

// add the image to the table row
tr1.addView(image1);
Gravitoid
  • 1,294
  • 1
  • 20
  • 20
8
  1. Have your activity implement View.OnClickListener
  2. Register your buttons to the listener
  3. Check which button is clicked in onClick
  4. Process your string depending on which button was clicked

    public class _Test2Activity extends Activity implements OnClickListener {
    
       private Button button1;
       private Button button2;
       private Button button3;
    
       private String myString;
    
       @Override
       public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
    
         button1 = (Button)findViewById(R.id.button1);
         button2 = (Button)findViewById(R.id.button2);
         button3 = (Button)findViewById(R.id.button3);
    
         button1.setOnClickListener(this);
         button2.setOnClickListener(this);
         button3.setOnClickListener(this);   
    
         myString = "This is a string";
    
       } 
    
       @Override
       public void onClick(View v) {
           if(v==button1) {
              //do something with myString
           } else if(v==button2) {
              //do something with myString
           } else if (v==button3) {
              //do something with myString
           }
       }
    }
    
Mark Pazon
  • 6,167
  • 2
  • 34
  • 50
1

If you have static content associated with the view, another option is to use a HashMap to map the view id to the content.

private static Map<Integer, String> idToStringMap = new HashMap<Integer, String>();

Initialize the map in onCreate:

idToStringMap.put(R.id.button1, "hello");
idToStringMap.put(R.id.button2, "world");
// ...

Then get the value from the view id in onClick:

public void onClick(View v) {

    String myString = idToStringMap.get(v.getId());
}

This is a little cleaner than using a long set of switch cases.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
1

In Kotlin :

Here i'm passing a view as a parameter onClick of Another view

define your Handler class object first in xml layout like this:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:bind="http://schemas.android.com/tools">
    <data>
        <import type="android.view.View" />
        <variable
            name="handler"
            type="com.demoapp.controllers.Handler" />
   </data>

and define button which perform click functionality.

<Button
  android:id="@+id/button2"
  android:onClick="@{(view) -> handler.getbuttonClickEvent(textViewId)}"
  .../>

and your text view like this: remember your TextView id will be converted like textViewId

<TextView
        android:id="@+id/text_view_id"
        ... />

final set up method in your Handler class

fun getbuttonClickEvent(view: TextView){
        view.text="Hello World"
    }
Geet Thakur
  • 1,966
  • 1
  • 16
  • 23
0

use implements OnClickListener like below code

public class Test extends Activity implements OnClickListener{
    Button btn1;
    Button btn2;
    Button btn3;
    Button btn4;
    Button btn5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //initialize btn...~~~

        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);
        btn4.setOnClickListener(this);
        btn5.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()) {
            case will be determine by Button's Id (R.id.blablabla)
        }
}
Joonsung Kim
  • 246
  • 1
  • 3
  • 15
0

Note that you do this in Kotlin a little differently from how you do it in Java. In Kotlin, you append NameOfParentClass() to the subclass declaration.

Now override Activity‘s onCreate() method. It will look something like this.

class MainActivity : AppCompatActivity() {
        private var btnClick: Button? = null
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            btnClick = findViewById(R.id.btnClick) as Button
            btnClick!!.setOnClickListener { startActivity(Intent(this@MainActivity, KotlinActivity::class.java)) }
        }
    }
Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164
Shraddha Patel
  • 149
  • 1
  • 5
-1

Another solution may be to not write the code directly inside onClick() method, alternatively, write the code in a separate method, and then call that method in onClick().

Example:

button.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    function();
   }
});

private void function() {
 //your code here
}