Best practice for defining button events in android

Haris Hasan picture Haris Hasan · Jun 16, 2011 · Viewed 86k times · Source

I have a Layout defined in XML which consists of several Buttons.

Currently I am doing this in the OnCreate method to define the event handlers against the buttons:

public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button newPicButton = (Button)findViewById(R.id.new_button);
    newPicButton.setOnClickListener(btnListener);
    ..... similarly for other buttons too
    .....
}

Inside of the Button's onClick event, I launch a camera Intent to get a picture and inside the onActivityResult callback I am again setting the event handlers along with setting the View like this:

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    setContentView(R.layout.main);
    Button newPicButton = (Button)findViewById(R.id.new_button);
    newPicButton.setOnClickListener(btnListener);
    ...similarly for other buttons too
}

I am new to android and this approach of redefining an event every time seems quite dirty to me. I would like to know what is the best practice in terms of defining button event handlers in scenarios like this.

Edit: pasting my complete class

public class CameraAppActivity extends Activity 
{
    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button newPicButton = (Button)findViewById(R.id.new_button);
        newPicButton.setOnClickListener(btnListener);
    }

    //---create an anonymous class to act as a button click listener---
    private OnClickListener btnListener = new OnClickListener()
    {

        public void onClick(View v)
        {   
             //Intent newPicIntent = new Intent(v.getContext(), NewPictureActivity.class);
             //startActivityForResult(newPicIntent, 0);
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, 999);
        } 

    };  

    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {  

        setContentView(R.layout.main);
        Button newPicButton = (Button)findViewById(R.id.new_button);
        newPicButton.setOnClickListener(btnListener);

       //if I comment last two lines nothing happens when I click on button

    }  

The main question is

setContentView(R.layout.main);
Button newPicButton = (Button)findViewById(R.id.new_button);
newPicButton.setOnClickListener(btnListener);

Re-registering events inside onActivityResult.. is it right approach? Or am I doing something wrong? Because If I don't re-register event nothing happens when I click the button.

Answer

Marqs picture Marqs · Jun 16, 2011

Why not registering onClick event in the XML layout and then handle it in the code. This is how I would do it:

<Button
android:id="@+id/my_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:onClick="onBtnClicked">
</Button>

and now create a method that would handle clicks

public void onBtnClicked(View v){
    if(v.getId() == R.id.my_btn){
        //handle the click here
    }
}

Alternatively, you can set the OnClickListener individually for each item in the code. Then use the if/else or switch statements to determine the origin.

This way you can have one method that handles all buttons from one layout.

UPDATE:
Although this is a valid approach I would strongly recommend the second option. It's cleaner and easier to maintain especially when you work with fragments.