Android App Development: Using Toasts and Alerts
Android offers two methods to display messages to the user: Toasts and Alerts. in this post we’re going to explore both of them.
Toasts:
toasts are pop up messages that lasts for a certain duration and then disappear. a Toast is a transient message that appears and disappears without any interaction from the user and with no notification to the program that it disappeared.
the Toast can display a simple text message or a complex view.
Displaying simple text:
to display a simple toast that displays a text message we use the following code:
Toast toast=Toast.makeText(this, "Hello toast", 2000); toast.setGravity(Gravity.TOP, -30, 50); toast.show();
we create the toast using the static Toast.makeText(Context con,String message, int duration) method to create a toast in the current context to display a text message for a duration specified in milli seconds or we can use the constant values Toast.LENGTH_SHORT to display for a short duration or Toast.LENGTH_LONG for longer duration.
The toast by default appears in the center of the screen, you can change the default position by specifying the Gravity and the X and Y offsets.
finally we call the Show() method to display the toast.
the previous toast will be like this:
Displaying complex views:
Toasts can also display complex views. this is done like this:
First: create a layout xml file in res/layout directory. the file must be named toast_layout.xml.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/toastView" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello toast" android:textColor="#000" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtDate" android:textColor="#000" /> </LinearLayout>
then from the code
Toast toast=new Toast(this); LayoutInflater inflater=this.getLayoutInflater(); View toastView=inflater.inflate(R.layout.toast_layout, (ViewGroup)findViewById(R.id.toastView)); TextView txtDate=(TextView)toastView.findViewById(R.id.txtDate); txtDate.setText("toast appeared at " +Calendar.getInstance().getTime().toLocaleString()); toast.setGravity(Gravity.CENTER, 0, 0); toast.setView(toastView); toast.show();
the toast will be like this:
- In the toast_layout.xml width, if you put any buttons or any control that has a callback, it would appear disabled and the user cannot interact with it.
- The toast can be created in two ways: by calling Toast.makeText method or by specifyinga view via setView method. when you want to display a simple text use the first one otherwise use the second. if you try to interchange or combine between the two methods an exception will be thrown.
Alerts:
another way to show interactive messages is to use Alerts. alerts act as MessageBox or JOptionPane in J2SE. they have buttons that can be used to take decisions.
Creating Alerts:
let’s check this example to create an alert and show it:
//declared as final to be able to reference it in inner class //declartations of the handlers final AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("Alert Dialog"); builder.setMessage("This is the alert's body"); builder.setIcon(android.R.drawable.ic_dialog_alert); builder.setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { TextView txt=(TextView)findViewById(R.id.txt); txt.setText("You clicked Ok"); } }); builder.setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText("You clicked Cancel"); } }); builder.setNeutralButton("Do something", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText("Neutral Button Clicked"); AlertDialog ad=builder.create(); ad.cancel(); } }); builder.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText(txt.getText()+" the cancel listner invoked"); } }); builder.show();
the previous code displays the following Alert:
the code may look bulky but it’s very simple.
first we create an instance of AlertDialog.Builder. we use the builder object to construct the AlertDialog object.
we specify the title and the icon of the alert. then the text to display in the body of the message.
the AlertDialog can display up to three buttons:
positive button: represents the OK button.
Negative button: represents the cancel button.
Neutral button: represents a button to perform another functionality other than ok or cancel.
note that there are no restrictions on the use of the three buttons, they can perform the same functionality the difference is just in logical meaning. but the three buttons cause the Alert dialog to dismiss.
we then specify the text and the click handler of each button.
in the neatral button click handler we added the lines AlertDialog ad=builder.create(); and ad.cancel();. the first line gets a reference to the current dialog created by the builder to provide additional functionality such as invoking cancel() method.
the cancel method raises the onCancel callback method.
we could have replaced the previous code with the following:
AlertDialog ad=builder.create(); ad.setMessage(message); ad.setIcon(icon); ad.setMessage(message); ad.setButton(text, listener); . . .
Displaying Custom Views:
alerts can display complex views rather than simple text messages. create an xml layout file called alertview.xml like this:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/toastView" android:background="#DAAA" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello alerts" android:textColor="#000" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtDate" android:textColor="#000" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/btnAlert" android:text="Click" /> </LinearLayout>
to display this view as the alert view we do it like this:
View bodyView=getLayoutInflater().inflate(R.layout.alertview, (ViewGroup)findViewById(R.id.toastView)); TextView txtDate=(TextView)bodyView.findViewById(R.id.txtDate); txtDate.setText(Calendar.getInstance().getTime().toLocaleString()); Button btnAlert=(Button)bodyView.findViewById(R.id.btnAlert); btnAlert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub TextView txtDate=(TextView)bodyView.findViewById(R.id.txtDate); txtDate.setText(Calendar.getInstance().getTime().toLocaleString()); TextView txt=(TextView)findViewById(R.id.txt); txt.setText(Calendar.getInstance().getTime().toLocaleString()); } }); builder.setView(bodyView); . . .
what is interesting in this approach is that the alert is fully interactive, by clicking the button you can change the value of any view in the alert or in the activity.
you can also set the title of the alert to be a custom view via builder.setCustomTitle(View v) method in the same way described above.
Displaying an alert of items:
alerts can display a list of items from which the user selects from like this:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"}; AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("Items alert"); builder.setItems(items, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText(items[which]); } }); builder.show();
this will display an alert like this:
notice that we do not have to specify any buttons because when the user clicks on any item the alert will be dismissed.
if the list items are in an Adapter we can achieve the same result using builder.setAdapter(Adapter ad,OnClickListener listner) method:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"}; ArrayAdapter arr=new ArrayAdapter(this, android.R.layout.select_dialog_item,items); AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("Adapter alert"); builder.setAdapter(arr, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText(items[which]); } });
or if the items are returned from a database in a cursor we can use
builder.setCursor(Cursor cursor, OnClickListener listner, String labelColumn)
Displaying alerts with items with choices:
we can add items to the alert with choices whether they are single choice (Radio buttons) or multiple choices (Check boxes).
to display single choice items:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"}; AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("List alert"); builder.setSingleChoiceItems(items, 0, new OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which){ // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText(items[which]); } }); builder.setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.show();
the second parameter of setSingleChoiceItems is an integer specifying the index of the selected item
notice that we added a postive button that when clicked dismisses the alert cause unlike the regular items list the alert won’t be dismissed when an item is selected.
the builder.setSingleChoiceItems method has other overloads that can accept an Adapter or a Cursor as parameters that hold the items to be displayed
to display multiple choice items:
final String [] items=new String []{"Item 1","Item 2","Item 3","Item 4"}; AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("List alert"); builder.setMultiChoiceItems(items, null, new OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { // TODO Auto-generated method stub TextView txt=(TextView)findViewById(R.id.txt); txt.setText(txt.getText()+" "+items[which]); } }); builder.setPositiveButton("OK", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); builder.show();
the second parameter of setMultiChoiceItems is an array of boolean values specifying which items are set selected. if you want no items to be selected then set it to null, otherwise specify an array with the same length of the items with boolean values indicating which item is selected and which is not like this:
new boolean[] {true,false,...}
works in the fashion as single items choice except that the selection here is multiple.
and that was everything about toasts and alerts, stay tuned for another tutorial next week/