To deal with a click of a button you have to provide an onClickListener function and link that function to your button. You might have many buttons on an activity. Some may share a function or have one each. I have discovered four ways of doing this.
First, lets look at the often used way. In the onCreate routine for the activity this is added:
final Button button1 = (Button) findViewById(R.id.cmd1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Context context = v.getContext();
String txtid = Integer.toString(v.getId());
CharSequence text = "Button 1 " + txtid;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
});
The main advantage of this method seems to be that all of the code is in one place, the function itself and the code to enable the function for a specific button is all there together. This also seems like a disadvantage to me too. A (potentially large) chunk of code is stuck in the onCreate function of the activity, rather than a simple statement to point to function in a separate part of the source file. Notice how there is a horrible "});" stuck at the end to show the nasty embedded nature of the declaration. Most of this code does not get run when the activity is created, but when a button is clicked, so why is it in the onCreate section?
The second example is in two parts, the first is in the onCreate of the activity which finds the button and points to the onClickListener routine
final Button button2 = (Button) findViewById(R.id.cmd2);
button2.setOnClickListener(cmd2_clicklistener);
The second part is the listener routine itself. This can be anywhere else in the source file, probably grouped with other listener routines.
private OnClickListener cmd2_clicklistener = new OnClickListener() {
public void onClick(View v) {
Context context = v.getContext(); //getApplicationContext();
String txtid = Integer.toString(v.getId());
CharSequence text = "Button 2 " + txtid;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
};
The main effect of this is to separate the listener routine from the onCreate area. It does still have a complication that there is a function declared within a function, but it is easier to read. many of these can be created separately, but also more than one button could share one listener, with the code checking which button called it if needed. Using these declarations that are separate from the allocation of the listener makes it possible to change the listener that responds to a button during the run time.
android:onClick="clickfunc".
This will cause a call to the function named which should have the prototype
public void clickfunc(View view).
This seems very simple yet having defined this the listener can still be overridden by a setOnClickListener call later just like the second example. There is no clutter in the onCreate section at all. It does, however, make the layout and code less independent. The listener in my example is this
public void cmd3_click(View v) {
Context context = v.getContext(); //getApplicationContext();
String txtid = Integer.toString(v.getId());
CharSequence text = "Button 3 " + txtid;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
The final way I have found to respond to clicks is not very flexible, but if your activity has a single button it works well, and still removes the clutter in the onCreate section. You can make your class contain an onClick function and set the listener to this. To do this you must add the extention implements onClickListener to the definition of the activity class. You can then add a handler for onClick to the class (outside of the onCreate section of course) like this
public void onClick(View v) {
Context context = v.getContext();
String txtid = Integer.toString(v.getId());
CharSequence text = "Button 4 " + txtid;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
The declaration of how to use the handler goes in the onCreate section as before, but now it simply points to the class itself (this).
final Button button4 = (Button) findViewById(R.id.cmd4);
button4.setOnClickListener(this);
I am pleased to have found alternatives to stuffing code into the onCreate section. Now I need to do the same for other listeners and handlers to make things much more readable.