Android OnClickListener - identify a button

310,794

Solution 1

You will learn the way to do it, in an easy way, is:

public class Mtest extends Activity {
  Button b1;
  Button b2;
  public void onCreate(Bundle savedInstanceState) {
    ...
    b1 = (Button) findViewById(R.id.b1);
    b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(myhandler1);
    b2.setOnClickListener(myhandler2);
    ...
  }
  View.OnClickListener myhandler1 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 1st button
    }
  };
  View.OnClickListener myhandler2 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 2nd button
    }
  };
}

Or, if you are working with just one clicklistener, you can do:

View.OnClickListener myOnlyhandler = new View.OnClickListener() {
  public void onClick(View v) {
      switch(v.getId()) {
        case R.id.b1:
          // it was the first button
          break;
        case R.id.b2:
          // it was the second button
          break;
      }
  }
}

Though, I don't recommend doing it that way since you will have to add an if for each button you use. That's hard to maintain.

Solution 2

Or you can try the same but without listeners. On your button XML definition:

android:onClick="ButtonOnClick"

And in your code define the method ButtonOnClick:

public void ButtonOnClick(View v) {
    switch (v.getId()) {
      case R.id.button1:
        doSomething1();
        break;
      case R.id.button2:
        doSomething2();
        break;
      }
}

Solution 3

I prefer:

class MTest extends Activity implements OnClickListener {
    public void onCreate(Bundle savedInstanceState) {
    ...
    Button b1 = (Button) findViewById(R.id.b1);
    Button b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(this);
    b2.setOnClickListener(this);
    ...
}

And then:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.b1:
            ....
            break;
        case R.id.b2:
            ....
            break;
    }   
}

Switch-case is easier to maintain than if-else, and this implementation doesn't require making many class variables.

Solution 4

Five Ways to Wire Up an Event Listener is a great article overviewing the various ways to set up a single event listener. Let me expand that here for multiple listeners.

1. Member Class

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //attach an instance of HandleClick to the Button
        HandleClick handleClick = new HandleClick();
        findViewById(R.id.button1).setOnClickListener(handleClick);
        findViewById(R.id.button2).setOnClickListener(handleClick);
    }    
    private class HandleClick implements OnClickListener{
        public void onClick(View view) {
            switch(view.getId()) {
            case R.id.button1:
                // do stuff
                break;
            case R.id.button2:
                // do stuff
                break;
            }
        }
    }
}

2. Interface Type

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(handleClick);
        findViewById(R.id.button2).setOnClickListener(handleClick);
    }
    private OnClickListener handleClick = new OnClickListener() {
        public void onClick(View view) {
            switch (view.getId()) {
            case R.id.button1:
                // do stuff
                break;
            case R.id.button2:
                // do stuff
                break;
            }
        }
    };
}

3. Anonymous Inner Class

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                // do stuff
            }
        });
        findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                // do stuff
            }
        });
    }
}

4. Implementation in Activity

public class main extends Activity implements OnClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.button1:
            // do stuff
            break;
        case R.id.button2:
            // do stuff
            break;
        }
    }
}

5. Attribute in View Layout for OnClick Events

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void HandleClick(View view) {
        switch (view.getId()) {
        case R.id.button1:
            // do stuff
            break;
        case R.id.button2:
            // do stuff
            break;
        }
    }
}

And in xml:

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="HandleClick" />
<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="HandleClick" />

Solution 5

If you don't want to save instances of the 2 button in the class code, follow this BETTER way (this is more clear and fast!!) :

public void buttonPress(View v) {
  switch (v.getId()) {
    case R.id.button_one:
        // do something
        break;
    case R.id.button_two:
        // do something else
        break;
    case R.id.button_three:
        // i'm lazy, do nothing
        break;
  }
}
Share:
310,794
xpepermint
Author by

xpepermint

Updated on October 06, 2020

Comments

  • xpepermint
    xpepermint over 3 years

    I have the activity:

    public class Mtest extends Activity {
      Button b1;
      Button b2;
      public void onCreate(Bundle savedInstanceState) {
        ...
        b1 = (Button) findViewById(R.id.b1);
        b2 = (Button) findViewById(R.id.b2);
        b1.setOnClickListener(myhandler);
        b2.setOnClickListener(myhandler);
        ...
      }
      View.OnClickListener myhandler = new View.OnClickListener() {
        public void onClick(View v) {
          // MY QUESTION STARTS HERE!!!
          // IF b1 do this
          // IF b2 do this
          // MY QUESTION ENDS HERE!!!
        }
      }
    }
    

    How do I check which button has been clicked?

  • Cristian
    Cristian almost 14 years
    Well, actually that's not correct. View is not a Button, but Button is a View. Though, you can cast a View to a Button. Keep in mind that the second way to do it is not recommended... maybe that v may not be a Button, which will generate a cast exception.
  • Andy Zhang
    Andy Zhang almost 14 years
    Another option would be to do a "if (v instanceof Button) { // Cast to Button and do stuff here }"
  • ognian
    ognian almost 14 years
    Actually both ways are not recommended, see my answer
  • slayton
    slayton over 12 years
    Its actually quite simple to replace the if, elses with a single switch case statement that you switch on the id of the view and the cases are id's from R.java
  • nuala
    nuala about 12 years
    Just wondering why you cast v to a Button anyway. getId() is defined for Views as well. Therefore I really wouldn't recommend the 2nd method but prefer Christian's solution!
  • Dennis
    Dennis over 11 years
    Much cleaner than the other answers that use a bunch of event handlers, if statements, and listeners. Listeners are great if buttons are created at runtime, but that's often not the case.
  • donfede
    donfede over 11 years
    While an interesting different approach, XML hooks for listeners are rough around the corners with Fragments, as the callback must reside in the activity (not the fragment).
  • gkiko
    gkiko about 11 years
    This worked perfectly. You need to implement OnClickListener-android.view.View and not OnClickListener-android.content.DialogInterface
  • Quasaur
    Quasaur about 11 years
    My prob is doSomething2() cant be reached without throwing either an InvocationTargetException or a NullPointerException (or both).
  • user1324936
    user1324936 over 9 years
    because it is no longer possible since v14 where ids are not treated not constant
  • SebasSBM
    SebasSBM almost 9 years
    @ognian I followed up to here because you said the main answer uses deprecated approaches. Nowadays with Android 5.0 Lollipop released, is your answer still true, or time made it become a falacy, like the comment above suggests? I really don't know what to think, or which direction to take from here.
  • Hubert Grzeskowiak
    Hubert Grzeskowiak about 8 years
    Just a sidenote: the statement "without listeners" here is wrong. You're only declaring the listener in XML, that's all.
  • cessor
    cessor over 7 years
    I came here looking for a method to pass additional parameters to a handler, this is exactly what I wanted. The tag can be declared in Markup.
  • Pang
    Pang almost 7 years
    This is more or less just a repeat of some of the existing answers.