By user591162


2011-04-07 23:30:06 8 Comments

I am building an Android Application. I've noticed that I am creating many repetitions of code similar to this in each of my classes:

Button buttonX = (Button)findViewById(R.id.buttonXName);
// Register the onClick listener with the implementation above
buttonX.setOnClickListener(new OnClickListener() {
    public void onClick(View v)
    {
        //DO SOMETHING! {RUN SOME FUNCTION ... DO CHECKS... ETC}
    } 
});

I now have fifteen buttons and this is making my code ugly. Does anyone have a class or some examples on how I can turn all these codes into something more efficient, so I can:

  1. Create the button object {Button buttonX (Button)findViewById(R.id.buttonXName);}
  2. Set the listener {buttonX.setOnClickListener(new OnClickListener()}
  3. Determine if it was clicked {public void onClick(View v)}
  4. Then run specific code for each button?

If anyone knows anything, I'd appreciate it.

9 comments

@Ilya Gazman 2013-05-07 19:16:36

Android lambada solution

public void registerButtons(){
    register(R.id.buttonName1, ()-> {/*Your code goes here*/});
    register(R.id.buttonName2, ()-> {/*Your code goes here*/});
    register(R.id.buttonName3, ()-> {/*Your code goes here*/});
}

private void register(int buttonResourceId, Runnable r){
    findViewById(buttonResourceId).setOnClickListener(v -> r.run());
}

Switch case solution solution

public void registerButtons(){
    register(R.id.buttonName1);
    register(R.id.buttonName2);
    register(R.id.buttonName3);
}

private void register(int buttonResourceId){
    findViewById(buttonResourceId).setOnClickListener(buttonClickListener);
}

private OnClickListener buttonClickListener = new OnClickListener() {

    @Override
    public void onClick(View v){
        switch (v.getId()) {
            case R.id.buttonName1:
                // TODO Auto-generated method stub
                break;
            case R.id.buttonName2:
                // TODO Auto-generated method stub
                break;
            case View.NO_ID:
            default:
                // TODO Auto-generated method stub
                break;
        }
    }
};

@raju dhiraj 2018-05-17 07:03:28

public class MyActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_options);

        Button button = findViewById(R.id.button);
        Button button2 = findViewById(R.id.button2);

        button.setOnClickListener(this);
        button2.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        int id = view.getId();

        switch (id) {

            case R.id.button:

                  // Write your code here first button

                break;

             case R.id.button2:

                  // Write your code here for second button

                break;

        }

    }

}

@yatin deokar 2018-02-09 05:25:56

Implement Activity with View.OnClickListener like below.

public class MyActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_options);

        Button button = findViewById(R.id.button);
        Button button2 = findViewById(R.id.button2);

        button.setOnClickListener(this);
        button2.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        int id = view.getId();

        switch (id) {

            case R.id.button:

                  // Write your code here first button

                break;

             case R.id.button2:

                  // Write your code here for second button

                break;

        }

    }

}

@Anil 2015-12-06 10:46:58

public class MainActivity extends AppCompatActivity  implements View.OnClickListener{

    Button b1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b1=(Button)findViewById(R.id.button);
        b1.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(),"Button is Working",Toast.LENGTH_LONG).show();
    }

}

@dgmltn 2011-04-07 23:52:21

If you're targeting 1.6 or later, you can use the android:onClick xml attribute to remove some of the repetitive code. See this blog post by Romain Guy.

<Button 
   android:height="wrap_content"
   android:width="wrap_content"
   android:onClick="myClickHandler" />

And in the Java class, use these below lines of code:

class MyActivity extends Activity {
    public void myClickHandler(View target) {
        // Do stuff
    }
}

@user591162 2011-04-08 00:16:43

Thank you. This is the perfect solution.

@Someone Somewhere 2011-10-07 21:27:46

weird, this didn't work with my Dialog. I got an exception saying the handler didn't exist, but I did definitely define the handler!

@Ilya Gazman 2014-06-27 13:01:00

@SomeoneSomewhere I think it search the view in the activity context. Handlers are out of game.

@tchelidze 2016-10-11 19:18:51

@dgmltn is it good practice to 'let view know about Activity internals' ?

@Wesagn 2012-05-25 21:20:45

You can use array to handle several button click listener in android like this: here i am setting button click listener for n buttons by using array as:

Button btn[] = new Button[n]; 

NOTE: n is a constant positive integer

Code example:

//class androidMultipleButtonActions 
package a.b.c.app;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class androidMultipleButtonActions extends Activity implements OnClickListener{
    Button btn[] = new Button[3];

    public void onCreate(Bundle savedInstanceState) {   
    super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        
        btn[0] = (Button) findViewById(R.id.Button1);
        btn[1] = (Button) findViewById(R.id.Button2);
        btn[2] = (Button) findViewById(R.id.Button3);
        for(int i=0; i<3; i++){
            btn[i].setOnClickListener(this);
        }           
    }

    public void onClick(View v) {
        if(v == findViewById(R.id.Button1)){
            //do here what u wanna do.
        }
        else if(v == findViewById(R.id.Button2)){
            //do here what u wanna do.
        }
        else if(v == findViewById(R.id.Button3)){
            //do here what u wanna do.
        }
    }
}

Note: First write an main.xml file if u dont know how to write please mail to: [email protected]

@Matthew Willis 2011-04-08 02:32:53

I think you can usually do what you need in a loop, which is much better than many onClick methods if it can be done.

Check out this answer for a demonstration of how to use a loop for a similar problem. How you construct your loop will depend on the needs of your onClick functions and how similar they are to one another. The end result is much less repetitive code that is easier to maintain.

@Squonk 2011-04-07 23:47:21

Implement OnClickListener() on your Activity...

public class MyActivity extends Activity implements View.OnClickListener {
}

For each button use...

buttonX.setOnClickListener(this);

In your Activity onClick() method test for which button it is...

@Override
public void onClick(View view) {
    if (View.equals(buttonX))
        // Do something
}

Also in onClick you could use view.getId() to get the resource ID and then use that in a switch/case block to identify each button and perform the relevant action.

@Corey Sunwold 2011-04-08 00:02:22

Is this really an improvement?

@Squonk 2011-04-08 00:29:06

@Corey Sunwold: It's all pretty subjective but using setOnClickListener(this); is a lot less ugly and reduces the button creation part of the code by not having inline onClick() declarations. Having only one onCLick() code block and, in particular, using a switch/case code block to identify which button is pressed puts an easy test in a separate area of main code. More than that, each 'case' could simply call a method in a 'helper' class located elsewhere. I can think of another way or two of doing things but code still has to go somewhere.

@Corey Sunwold 2011-04-08 14:57:24

Squonk: That makes more sense, I hadn't considered it from a testability standpoint (probably should have). Thanks.

@Jim Blackler 2011-04-07 23:49:39

Since setOnClickListener is defined on View not Button, if you don't need the variable for something else, you could make it a little terser like this:

findViewById(R.id.buttonXName).setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    //DO SOMETHING! {RUN SOME FUNCTION ... DO CHECKS... ETC}
    } 
});

Related Questions

Sponsored Content

11 Answered Questions

[SOLVED] Proper use cases for Android UserManager.isUserAGoat()?

97 Answered Questions

[SOLVED] Close/hide the Android Soft Keyboard

48 Answered Questions

[SOLVED] Is there a unique Android device ID?

30 Answered Questions

30 Answered Questions

[SOLVED] How to create an HTML button that acts like a link?

25 Answered Questions

[SOLVED] Is there a way to run Python on Android?

14 Answered Questions

[SOLVED] <button> vs. <input type="button" />. Which to use?

18 Answered Questions

[SOLVED] Fling gesture detection on grid layout

Sponsored Content