Creating and Displaying an About Box using an AlertDialog
In this lesson we learn how to create and display an About Box using an AlertDialog, onCreateDialog, showDialog(int) and the AlertDialog.builder.
When the user selects "About" from the context menu, we will need to display an About dialog. The simplest way to do this is to create an Alert dialog using the AlertBuilder. In the next lesson we will create a more complicated dialog as a custom dialog. Here again is the onOptionsItemSelected method from the previous lesson:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.manage_password:
;
return true;
case R.id.options:
;
return true;
case R.id.about:
this.showDialog(DIALOG_ABOUT);
return true;
default:
return super.onOptionsItemSelected(item);
}
The the user selects "About" from the context menu, the event will be trapped in the onOptionsItemSelected method calling this.showDialog(DIALOG_ABOUT). But where is the About Dialog created? Well, on the first call to showDialog the Android OS will send an event to the onCreateDialog method. That is where we should create the actual About Dialog. First add the necessary import to ConfuseText.java:
import android.app.Dialog;
Next, add the onCreateDialog handler to the ConfuseText.java class as:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_ABOUT:
// do the work to define the About Dialog
dialog= getInstanceAlertDialog();
break;
default:
dialog = null;
break;
}
return dialog;
}
Then add the getInstanceAlertDialog method as:
private AlertDialog getInstanceAlertDialog() {
AlertDialog.Builder builder= new AlertDialog.Builder(this);
builder.setMessage("Confuse Text JALComputing Copyright 2011");
AlertDialog alert= builder.create();
alert.setTitle("About");
return alert;
}
The Android OS will call onCreateDialog "the first time" creating one instance of our About Dialog. Here is our exciting code in action:
When the user selects the "back" button, the dialog is dismissed.
It is possible to embed returns using %n in the alert string as in:
private String alertMessage= String.format("Confuse Text%nJALComputing%nCopyright 2011");
Alternatively you can embed "\n" in the text itself. Using %n is a cross platform habit. It is also possible to get the app versionName (eg 1.2) as:
import android.content.pm.PackageManager.NameNotFoundException;
private String versionName="0";
private String appPackageName= "jalcomputing.confusetext";
try {
versionName= getPackageManager().getPackageInfo(appPackageName, 0).versionName;
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
versionName= "0";
}
Finally, add a "Dismiss" button to our About Dialog by adding the code in red seen below.
private AlertDialog getInstanceAlertDialog() {
AlertDialog.Builder builder= new AlertDialog.Builder(this);
try {
versionName= getPackageManager().getPackageInfo(appPackageName, 0).versionName;
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
versionName= "0";
}
builder.setMessage(alertMessage+"Version: "+versionName);
AlertDialog alert= builder.create();
alert.setTitle("About");
alert.setButton("Dismiss", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return alert;
}
Now the user can dismiss the dialog by hitting the "Dismiss" button or by hitting the back button.
Mutable Alert Dialog
Using onCreateDialog means that the Android OS will handle configuration changes automagically. If you want to change the state of an alert dialog created using onCreateDialog, override onPrepareDialog as in:
// ON_PREPARE_DIALOG synch widgets here
protected void onPrepareDialog(int id, Dialog d){
switch(id) {
case DIALOG_OPTIONS:
cbOptionShowCharCount.setChecked(isShowCharCount);
cbOptionAutoLaunch.setChecked(isAutoLaunch);
cbOptionTagCipherText.setChecked(isTagCipherText);
switch(timeoutType) {
case PasswordState.TIMEOUT_NEVER:
radioGroupTimeout.check(R.id.radio_never);
break;
case PasswordState.TIMEOUT_MONTHLY:
radioGroupTimeout.check(R.id.radio_monthly);
break;
case PasswordState.TIMEOUT_WEEKLY:
radioGroupTimeout.check(R.id.radio_weekly);
break;
case PasswordState.TIMEOUT_DAILY:
radioGroupTimeout.check(R.id.radio_daily);
break;
}
break; // CASE_DIALOG_OPTIONS
} // END SWITCH
}
If you do NOT need or desire to persist the alert dialog on orientation change, you do not need to implement onCreateDialog and may call dialog.show() directly. Alternatively, you can call builder.create().show(). Here is an example that does not use onCreateDialog or showDialog(int):
// Pop Up Mutable Alert
private void alertMessageReceived(String msg){
if (msg == null){
msg= "Message From Unknown Caller";
}
AlertDialog.Builder builder= new AlertDialog.Builder(this);
builder.setTitle("ConfuseText Alert");
builder.setMessage(msg);
builder.setCancelable(true);
builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//cancels itself?
}
});
builder.setNegativeButton("LATER", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ConfuseText.this.finish();
}
});
builder.create().show();
}
This alert dialog will NOT persist on orientation change.
Adding a Stateful EditText Box
It is possible to add an EditText box to an AlertDialog as in:
AlertDialog.Builder builder= new AlertDialog.Builder(this);
EditText myView= new EditText();
builder.setTitle("About");
builder.setMessage(alertMessage+"Version: "+versionName);
builder.setView(myView);
AlertDialog alert= builder.create();
The edit text box does not have an ID and the state will not be saved on a soft kill. If you want the OS to save state, you would need to create a simple layout in res/layout as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText android:text="Stateful"
android:id="@+id/EditText01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
And inflate this layout, passing it to builder.setView as in:
AlertDialog.Builder builder= new AlertDialog.Builder(this);
LayoutInflater inflater= getLayoutInflater();
final View myView= inflater.inflate(R.layout.alert_dialog_text_entry, null);
builder.setTitle("About");
builder.setMessage(alertMessage+"Version: "+versionName);
builder.setView(myView);
AlertDialog alert= builder.create();
Now the state of the EditText box will be saved on a soft kill (orientation change) automagically by the OS.
It is also possible to create an About Box as a separate Activity. To do this, we would trap for the About event in the onClick listener, create a new Intent using our About class, and call startActivity on myNewIntent.
OK, now I have a headache!
JAL