Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for defining button events in android

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.

like image 420
Haris Hasan Avatar asked Jun 16 '11 12:06

Haris Hasan


People also ask

What are the two ways of defining a click event for a button?

There are two ways to do this event handler programmatically : Implementing View. OnClickListener in your Activity or fragment.

Which method is used to handle button click events?

When the user clicks a button, the Button object receives an on-click event. To define the click event handler for a button, add the android:onClick attribute to the <Button> element in your XML layout. The value for this attribute must be the name of the method you want to call in response to a click event.

How does Android handle multiple click events?

Show activity on this post. call setClickable(false) for all buttons once one of them was clicked. call the next activity with startActivityForResult(...) override onActivityResult(...) and call setClickable(true) for all buttons inside it.

What is OnClickListener method in Android?

In Android, the OnClickListener() interface has an onClick(View v) method that is called when the view (component) is clicked. The code for a component's functionality is written inside this method, and the listener is set using the setOnClickListener() method.


2 Answers

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.

like image 92
Marqs Avatar answered Sep 27 '22 20:09

Marqs


Here is the best approach with code:

  public class MyTest extends Activity implements OnClickListener{      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);      //... some other code here to init the layout         Button btn1 = (Button)findViewById(R.id.button1);         Button btn2 = (Button)findViewById(R.id.button2);         btn1.setOnClickListener(this);         btn2.setOnClickListener(this);     }      @Override     public void onClick(View v) {         switch(v.getId()){             case R.id.button1:                 break;             case R.id.button2:                 break;         }     } } 

The new class with an interface is only good if you want to decouple the implementation (when you want to use the same class code somewhere else, move it to another seperate class file etc..) but in general if you are doing things connected with the current activity you are on and the onClick implementations depend on it running with reference to the objects defined there you should definitely use the method i suggested.

Creating class interfaces is only good when you want to achieve communication between seperate classes or activities and keep things apart. other than that its a bad practice creating subclasses for this.

like image 40
DArkO Avatar answered Sep 27 '22 22:09

DArkO