Android OnClickListener - identify a button

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?


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.


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

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.


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" />

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