I have a Layout
defined in XML which consists of several Button
s.
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.
Why not registering onClick event in the XML layout and then handle it in the code. This is how I would do it:
and now create a method that would handle clicks
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.
There is no best practice defined. It heavily depends on the use case. You could define them in your XML layout using the Button's
onClick
attribute.XML example:
Java example:
That way you don't have to implement the
OnClickListener
yourself. You can assign each Button the sameonClick
method and then simply decide on a per-view basis what action to trigger or you can have a separate method for every Button.In general I advice against using one
OnClickListener
for more than one Button. It is easier to understand what each listener is supposed to do if you use descriptive names which is what you should do anyway.Here is how I did it:
@Override
It works Great.
The problem is the object for the button newPicButton is being created as a local object which is valid only in the scope of the function onCreate and as soon as the code exits that function the garabage collector deallocates the object for the button. what you need to do is declare the newPicButton object outside any method and then in onCreate method assign it a listener. This will solve your problem and i hope i have explained why nothing happens when you remove the code for the newPicButton in the onActivityResult method :)
this is the best approach
I know this is old, but if anyone is wondering why you cannot add
onClickListener
fromonActivityResult
, that is because the button is null. If you initialize it once again (just as you did inonCreate
), you can add the listener. Be careful, though, everything else will be null as well, so if you are taking data from anEditText
, for example, you have to initialize that, as well (a simple check if the object is null in the lisneter will do the trick).