Chapter 7. UI Design: Buttons, Menus, and Dialogs

The UI design determines the usability of your application, which will ultimately determine its success and even its profitability if you are selling it.

A standard UI is composed of a number of familiar components that can be used by your application's users to control their user experience (often called the UX). These UI elements include items such as buttons, check boxes, menus, text fields, dialog boxes, system alerts, and similar widgets.

This chapter covers how to use several of the most important Android widgets for UI design. First, we'll cover adding image buttons, text, and images to your UI. Then you'll learn about the different types of menus available. Finally, we'll cover displaying dialogs, including alerts, which carry messages to your application user. There's a lot of cool stuff to cover, so let's get started.

Using Common UI Elements

Android has all of the standard UI elements already coded and ready to use in a single package called android.widget. Here, we'll explore how to add an image button, text area, and image to your app's UI.

Note

Recall that a package in Java is a collection of ready-to-use classes that you can leverage within your application. You just need to tell Java that you are going to use them by importing them via the Java import command.

Adding an Image Button to Your Layout

In Chapter 6, we crafted a UI that included the Button class, which is used to create the standard Android system format buttons, and lets you do so with the greatest of ease. Now, we'll look at the more complex ImageButton class. For professional, customized, high-graphics UIs, this is the class that you will need to use to gain the most control over the user experience.

The android.widget package's ImageButton class allows you to use your own imagery to create custom multistate buttons that are cooler looking than the standard buttons that come with the Android operating environment.

There is a distinct work process to creating a successful multi-state 24-bit PNG image button, which will composite perfectly over background imagery using an 8-bit alpha channel.

Android supports 24 bits of PNG image data, with another 8 bits of anti-aliased image transparency channel (requiring another 8-bit alpha channel). Let's do the math: 24 + 8 = 32. So, what we really have is a 32-bit PNG image, with 8 bits of data for each of the red, green, and blue image channels, and another 8 bits of data for the alpha (transparency) channel.

In case you're not familiar with some of the terms I used in the previous description, here are some brief definitions:

  • Compositing: The process of using layers to form a single new image out of more than one component part.

  • Alpha channel: That part of each layer that is transparent, and thus does not hold any image data passing through visible image data from other layers underneath it.

  • Anti-aliasing: The edge treatment that is used to make the edges of images within these transparency layers perfectly smooth when these edges are not perfectly square, which they rarely are.

Defining Multistate Image Button Graphics in XML

The XML markup is a bit more complex for multistate image buttons than it is for regular buttons. Your XML file needs to tell Android which image to use for each state of the button:

  • Pressed (for touchscreens, the pressed image will be shown when the finger is touching a button image on the screen)

  • Released or normal

  • Focused (in use or last touched)

Let's look at the code for our button1.xml file, which we will reference later when we create our ImageButton XML entry in the main.xml file that goes in the /res/layout folder. You don't need to create this file now. In fact, when we get to that point in our example, you'll see that Eclipse creates this file for you automatically!

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true"
                android:drawable="@drawable/button1_pressed" />
        <item android:state_focused="true"
                android:drawable="@drawable/button1_focused" />
        <item android:drawable="@drawable/button1_normal" />
</selector>

The first line is the standard first line of every XML file that you code, and it will always say the same thing.

The second line defines a selector tag and points to its XML schema, as you have seen in previous chapters. A selector tag allows selection between several options. Inside the selector tag, we nest three item tags to show which drawable (bitmap) images to use for state_pressed=true, state_focused=true, and the default or normal button state.

For this XML code to work, we must have three 24-bit bitmap PNG images in our project's /res/drawable folder named button1_pressed.png, button1_focused.png, and button1_normal.png.

Note

Recall that each of the image file names must use only lowercase letters and numbers, and can also use the underscore character.

The first item tag has an android:state_pressed attribute, which is set equal to true, and a second android:drawable attribute, which is set equal to the location of the file and its name (sans the .png extension).

The @ equates to your project's resources folder, /project/res/, so in this case, @drawable/button1_pressed will equate to c:/projects/imagebuttons/res/drawable/button1_pressed.png in the Android compiler. The other item tags follow the same format as the first one.

Creating the UI Image Button Project in Eclipse

Now that we've reviewed the concepts, let's create the project for real. As you've done in previous chapters, fire up Eclipse and choose select File

Creating the UI Image Button Project in Eclipse
  • Project name: Name the folder Chapter7.

  • Build Target: So our application runs on all of the popular Android operating system versions from 1.5 through 3.0, choose Android 1.5.

  • Application name: We'll call this application UI Examples.

  • Package name: Using the proper package name form, enter chapter.seven as the name.

  • Create Activity: Check this box and name the activity UserInterface.

  • Min SDK Version: Enter 3, to complement the build target choice.

Figure 7-1 shows the completed New Android Project dialog for our multistate image button example. Click Finish after you've filled it in.

Completed New Android Project dialog for our Chapter7 project

Figure 7.1. Completed New Android Project dialog for our Chapter7 project

Creating the button1.xml File

You now have an empty Eclipse project. Next, we'll create the button1.xml file so we can add the button state definition XML we created earlier.

Open the project tree on the left Package Explorer tab and expand the src folder by clicking the arrow. Then right-click the drawable folder and select New

Creating the button1.xml File
Creating a new file in the drawable folder to hold our XML

Figure 7.2. Creating a new file in the drawable folder to hold our XML

In the New File dialog, ask Eclipse to create the file button1.xml in the Chapter7/res/drawable folder, as shown in Figure 7-3. Then click Finish to create an empty text file. This is one of the most basic ways that you can have Eclipse create a new, empty text file for you. We will cover other ways of creating new XML files in later chapters.

Specifying the drawable folder and button1.xml file name in the New File dialog

Figure 7.3. Specifying the drawable folder and button1.xml file name in the New File dialog

Click the button1.xml tab at the top of your screen, and then type in the XML code that defines the selector and item tags for setting the three different image button states:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true"
                android:drawable="@drawable/button1_pressed" />
        <item android:state_focused="true"
                android:drawable="@drawable/button1_focused" />
        <item android:drawable="@drawable/button1_normal" />
</selector>

After you've entered the XML, you'll notice that Eclipse shows that there are three errors in the markup relating to missing file assets. Place your mouse over the red X on the left margin by the markup code. This pops up a diagnostic message regarding why Eclipse thinks this code needs your attention, as shown in Figure 7-4.

Eclipse shows us that our three image state buttons are missing via error flags in the IDE.

Figure 7.4. Eclipse shows us that our three image state buttons are missing via error flags in the IDE.

We have not put the three image button images in the /res/drawable folder where they belong. Eclipse is telling us that it does not see each file name that is referenced in the markup in the directory where it is supposed to be.

Note

Once we add valid XML specifiers and code, the Eclipse error messages will disappear. But this does show how Eclipse is watching out for you in real time, and offering warnings about what might be missing, what might generate compiler errors, and other common problems.

Let's create the three button state files. I'm going to use Photoshop, but other good drawing tools can do the same thing. Also, these PNG images are provided with the book code examples, so you do not need to create them from scratch if you would rather not do that.

Just as in the examples in previous chapters, put the graphics on a transparency layer (indicated in Photoshop by a checkerboard pattern), so that you can overlay the image button on any background color or image you like. Figure 7-5 shows the completed images in Photoshop.

Our multistate image button images in Photoshop showing alpha channel transparency areas

Figure 7.5. Our multistate image button images in Photoshop showing alpha channel transparency areas

Whenever you add new images or other assets to Eclipse, you need to tell Eclipse about the new assets. To do this, right-click the top-level project folder and select Refresh, as shown in Figure 7-6. You'll notice that the red errors no longer appear in the file.

Tip

There is also a deeper level of refreshing called validating, which will go into even deeper depths in your code and image assets. If the red error marks do not disappear, simply right-click the Chapter7 top-level folder again and choose the Validate option.

Using the Refresh menu option to tell Eclipse that our images are now in the drawable folder

Figure 7.6. Using the Refresh menu option to tell Eclipse that our images are now in the drawable folder

Editing the main.xml File

Next, open the res folder and right-click the main.xml file to open it for editing. Notice that our image button source files now appear in the Package Explorer pane.

We need to replace the default text tag in the main.xml file with an ImageButton tag, as follows:

<ImageButton android:id="@+id/button_one"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/button1"
             android:paddingTop="5px">
</ImageButton>

Figure 7-7 shows the IDE at this point.

Eclipse with a successful refresh and new ImageButton tag

Figure 7.7. Eclipse with a successful refresh and new ImageButton tag

The first attribute adds an ID of button_one to the ImageButton so we can access it inside our Java code. The next two lines define the width and height of the image button via the wrap_content attribute—all very standard Android programming fare.

The next line accesses the button1.xml file that we have created to reference the various image button states. Notice that you do not need to add the .xml extension here, just as you don't need to add .png for graphic files. We add 5 pixels of padding to the top of the image, just to practice using padding values.

Figure 7-8 shows how our UI Examples app looks when run in the Android 1.5 emulator (right-click Chapter7 and select Run As

Eclipse with a successful refresh and new ImageButton tag
Our multistate image button running in the Android 1.5 emulator

Figure 7.8. Our multistate image button running in the Android 1.5 emulator

When you click the image button, it changes color and uses the standard orange background to highlight the button being clicked.

Since we want just the image to be the button (which is why we used transparency and an alpha channel in Photoshop), we will set a background color, or transparency, next.

Replacing the Default Background

We do not want to use the default Android button background. We want the background to be transparent so we can use this ImageButton to put an image on top of a button and its text, as well as being able to make the image itself into a button.

In this example, we are changing the color of the button, rather than changing the size or shape of the button, so the transparent area remains exactly the same, pixel for pixel, between the different image state graphics. Thus, we can either set the background image to our normal button state or set the background color to 100% transparent 32-bit alpha channel with the #00000000 setting (which means zero red, zero green, zero blue, zero alpha). This is similar to setting HTML color with the pattern #RRGGBBAA. That is the most elegant solution, so let's implement that now.

We'll do this in a new way, so that you learn how to use another cool Eclipse function that helps you design your UI widgets and layouts. I think this is a really slick trick, and it was pretty difficult to figure out. As such, this is fairly advanced. Stick with it, though, and you won't be disappointed.

Click the main.xml tab at the top of your screen, and then click the Layout tab at the bottom of the pane that shows your XML for the ImageButton (see Figure 7-9). Eclipse will render your XML markup exactly as it would look in the emulator. Eclipse also provides (on the left) drag-and-drop widgets and layouts, so you can visually design your UI. The normal work process is to switch back and forth between the XML markup coding tab and the visual layout editor tab so you can make sure your XML code is nested properly. This is also a great way to learn XML layout and UI coding in Android.

Using the Eclipse visual layout editor and Properties tab to set your image background to transparent

Figure 7.9. Using the Eclipse visual layout editor and Properties tab to set your image background to transparent

An even cooler tab is the Properties tab at the bottom of the screen. This tab shows all of the properties assigned or available to the UI element tag that you have selected in the layout view. Click the button element, and a red line will surround the button, showing you what is currently actively selected. In the Properties tab, you will see all of the properties and variables that you can set and customize for the ImageButton class.

Click the Background property in the Properties tab to highlight it. Eclipse then provides a button to search for a file to use as a background image.

Since we are just going to set the background to transparent, we do not need to use this button for the example. Instead, type the transparency value #00000000 into the field next to Background in the Properties tab, as shown in Figure 7-9. Then click somewhere else in the IDE. The value will be accepted and the results displayed in the Layout tab!

That finishes up our custom image button. Next, let's look at how to add text to your app's UI.

Adding a Text to Your Layout

Besides buttons, another common UI element is text. Android provides the TextView class to implement text in a UI.

Since we are using the visual layout editor in Eclipse, let's continue to explore its functionality. Click the left header bar called Layouts to close the layouts selection view, leaving only the Views (remember widgets are really views) pane open. Clicking these headers will toggle them open and shut at any time (try it now if you don't believe me).

Next, click the scrollbar (gray, with a tiny arrow) until you see the TextView widget. Select and drag (and drop) it into the Layout view window under the ImageButton. Our TextView is now in the UI view and is ready to customize by using the Properties tab at the bottom of the Eclipse IDE. Let's do that now.

Scroll down to the Text properties and set up some custom values, such as Sample Text, and a text color of gold to match the ImageButton default image (an RGB value of #CCCC77 will work well; this is a hexadecimal numeric representation of a 24-bit value). Figure 7-10 shows the Eclipse IDE at this point.

Using the Eclipse visual layout editor to add and configure a TextView widget in the main.xml file

Figure 7.10. Using the Eclipse visual layout editor to add and configure a TextView widget in the main.xml file

Finally, we'll set a dpi value for padding, so that there is some space around our TextView. Scroll to the Padding properties in the Properties tab at the bottom of your Eclipse IDE, and type in 12dip, as shown in Figure 7-11. Then click another field, and you will see the text space itself out.

Setting the padding for our TextView via the Properties tab in the Eclipse IDE

Figure 7.11. Setting the padding for our TextView via the Properties tab in the Eclipse IDE

Adding an Image

Finally, let's add another popular type of UI element used for design: the image. Go to the code bundle for this book and copy the two 32-bit image files named image1.png and image2.png into your Chapter7/res/drawable folder.

Right-click the Chapter7 folder in the Package Explorer pane and refresh the project.

Now, let's add an ImageView tag to our XML. To do this, drag the ImageView from the Views list on the left and drop it under the TextView. This gives us a LinearLayoutViewGroup containing ImageButton, TextView, and ImageView tags.

Next, in the Properties tab below the visual editing window, click the Src (for Source) property, and then click the button on the right with three dots (ellipsis) to open the Reference Chooser dialog. Open the Drawable folder and select image1 for our ImageView source imagery, as shown in Figure 7-12. Click the OK button to close the dialog.

Choosing our image resource via the Reference Chooser dialog, accessed by clicking the ellipsis in the Src field in the Properties tab

Figure 7.12. Choosing our image resource via the Reference Chooser dialog, accessed by clicking the ellipsis in the Src field in the Properties tab

In your visual layout tab, you will now see the image and how its transparency area composites smoothly with the black background color.

Later, when we add a menu to our app, we will change the background color to white to show how this image transparency can help with UI compositing over different background colors or imagery.

So now in the next screen, you will see our ImageButton, TextView, and ImageView with enough screen area to hold a bottom menu of icons. Also note that we used the drop-down at the top to change our orientation to Portrait mode, as shown in Figure 7-13. This orientation fits our application design better. We'll add menus in the next section.

Changing our visual editing environment orientation to portrait

Figure 7.13. Changing our visual editing environment orientation to portrait

Using Menus in Android

Menus in Android are quite different from the top-mounted text menus found directly beneath the title bar in PC applications. The menu function on a smartphone is a bit different for ease of use, and is an actual physical button called Menu on Android phones.

Pressing the Menu button calls up a menu, which is—you guessed it—at the bottom of the screen, instead of at the top. To make it even more user-friendly, it is composed of five large square icons that can be easily touched to control application features.

For our application, we will have our menus do things with our ImageView object, background color, and alert dialog (which we'll add later in the chapter), so that everything we cover in this chapter ties together.

Creating the Menu Structure with XML

As you might have guessed, you set up your entire menu structure in an XML file. The menu XML file goes in a /res subfolder named menu, as required by Android. So, first create a folder under the /res folder called menu. Next, right-click the Chapter7 project folder, select New

Creating the Menu Structure with XML
<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/buttonone"
          android:icon="@drawable/image1icon"
          android:title="@string/showimage1" />

    <item android:id="@+id/buttontwo"
          android:icon="@drawable/image2icon"
          android:title="@string/showimage2" />

    <item android:id="@+id/buttonthree"
          android:icon="@drawable/menu3icon"
          android:title="@string/showwhite" />

    <item android:id="@+id/buttonfour"
          android:icon="@drawable/menu4icon"
          android:title="@string/showblack" />

    <item android:id="@+id/buttonfive"
          android:icon="@drawable/menu5icon"
          android:title="@string/showalert" />
</menu>

The menu XML tag is fairly straightforward. It simply declares the location of its XML schema definition and nested item tags that specify attributes for each menu item to be added. The Android menu holds five items comfortably, and it can hold more than that via a sixth item that drops down a submenu. Most Android applications use five or fewer menu items.

Each of the item tags has the following three attributes:

  • The android:id attribute allows the item tag to be given a name and referenced in your Java code.

  • The android:icon attribute is the location of the graphic file that will be used for the menu icon. In the first item, it is located in the Chapter7/res/drawable folder and named image1icon.png, shown in Android shorthand as @drawable/image1icon.

  • The android:title attribute is the title or label for the menu button. The title is in the strings.xml file, where text constants are defined (we'll do that next).

Figure 7-14 shows the completed Chapter7/res/menu/menuname.xml file. The figure also shows the five icon files (image1icon, image2icon, menu3icon, menu4icon, and menu5icon) placed in the /res/drawable folder, where Android looks for image files for the application. The images are all 24-bit PNG files with transparency, as you will see when they appear on our menu's buttons.

View of the mainmenu.xml file showing menu and item tags. Also note the menu icons in the drawable folder.

Figure 7.14. View of the mainmenu.xml file showing menu and item tags. Also note the menu icons in the drawable folder.

Defining Menu Item Strings

Next, we'll go into the strings.xml file in the /res/values folder (under the menu folder in the Package Explorer pane) to edit our application's string constants. We'll add the text for our five menu items. Follow these steps to add the five string values specified in our mainmenu.xml file:

  1. Right-click the strings.xml file and select Open to open it in a tab for editing in the Eclipse IDE, as shown in Figure 7-15.

    Adding string values for our menu items in the visual editor in Eclipse IDE

    Figure 7.15. Adding string values for our menu items in the visual editor in Eclipse IDE

  2. Click the Resources tab at the bottom of the pane to see a visual representation of the values in the strings.xml file.

    Tip

    Remember that if you want to see the XML, click the strings.xml tab next to it. You can switch back and forth between the code view and the helper view which is a great way to learn how to code XML UI elements!

  3. Click the Add button to bring up the dialog shown in Figure 7-16. Select String and click OK to add a string to our strings.xml file.

    Selecting a String element in the resource selection dialog in the add string resource work process

    Figure 7.16. Selecting a String element in the resource selection dialog in the add string resource work process

  4. In the area on the right, in the Name field, enter showimage1. In the Value field, enter IMAGE ONE. Click the Add button to add this string value to the strings.xml file.

  5. Repeat steps 3 and 4 to add four more string values with the following names and values:

    • showimage2, IMAGE TWO

    • showwhite, USE WHITE

    • showblack, USE BLACK

    • showalert, SHOW ALERT

  6. Set our default black background color of #000000 as a Color object, as shown in Figure 7-17.

    Editing the background color resource in the strings.xml file via the Eclipse visual editor

    Figure 7.17. Editing the background color resource in the strings.xml file via the Eclipse visual editor

  7. Add a white background called background2, using a value of #FFFFFF.

Inflating the Menu Structure via Java

Now it is time to add in our Java code, which inflates our menu from the XML file into our application's memory. The term inflating a resource describes the process of the Android operating system taking the data described in an XML file and populating an object that can be accessed and used in Java. In this case, it is our mainmenu object, which contains five menu selection buttons, their icon resources, and the text captions.

Here is the Java code to add to our UserInterface.java file:

public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        return true;
}

Android has a dedicated Java object for inflating XML code constructs into an object-based format for use with Java. This is precisely what you are seeing here inside the onCreateOptionsMenu() method, which uses the inflate() method and the R.menu.mainmenu path to our mainmenu.xml file. It creates the inflaterMenuInflater object, which contains our inflated menu objects. The R equates to the res folder of our project, so R.menu.mainmenu is equivalent to c:/Projects/Chapter7/res/menu/mainmenu.xml.

We also added two import statements at the top of our code to tell Android which UI code we would be using. We specify android.view.Menu and android.view.MenuInflater, which form the foundation for our menu and its inflation from the XML format.

import android.view.Menu;
import android.view.MenuInflater;

Figure 7-18 shows the code added to UserInterface.java.

Creating our menu using the MenuInflater in the Eclipse IDE Java editing pane

Figure 7.18. Creating our menu using the MenuInflater in the Eclipse IDE Java editing pane

Note that we have implemented our application's options menu in little more than a half-dozen lines of Java code. We have offloaded about 80% of the menu implementation coding to XML, and we can continue to add features and fine-tune menu options inside the XML markup as well.

Running the Application in the Android Emulator

Let's run our code and see our menu in action. Right-click the Chapter7 folder in the Package Explorer pane and select Run As...

Running the Application in the Android Emulator
Running our application in the Android 1.5 emulator

Figure 7.19. Running our application in the Android 1.5 emulator

As you can see, the Android phone has a prominent Menu button, which we can press to display our menu at the bottom of the screen. You can see the translucency of the menu. If you look closely at the first button, you will see the bottom of the ImageView behind the menu. If you click the various buttons, they will highlight in orange and close the menu, which you can reopen with the Menu button.

So, the default way an empty menu works is harmless to the application. It allows us to develop and test the way our menu looks via XML before we add in the Java logic to implement the actions that will be called when each button is pressed.

Making the Menu Work

Let's add our menu item implementations now. First, we need to give our LinearLayout an ID, so that we can find it in our code.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/uilayout"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

Now, we need to implement the onOptionsItemSelected() method, where we code the choices between our different menu item selections and what they do in our application if and when they are selected.

public boolean onOptionsItemSelected(MenuItem item) {
    LinearLayout bkgr = (LinearLayout)findViewById(R.id.uilayout);
    ImageView image = (ImageView)findViewById(R.id.ImageView01);

        switch (item.getItemId()) {

        case R.id.buttonone:
                        image.setImageResource(R.drawable.image1);
                        return true;
        case R.id.buttontwo:
                        image.setImageResource(R.drawable.image2);
                        return true;
        case R.id.buttonthree:
                        bkgr.setBackgroundResource(R.color.background2);
                        return true;
        case R.id.buttonfour:
                        bkgr.setBackgroundResource(R.color.background);
                        return true;
        case R.id.buttonfive:
                        // The Alert Code For Next Section Goes Here!
                        return true;
        default:
                return super.onOptionsItemSelected(item);
        }

    }

This code is a bit more complex than our MenuInflater code. At its core, it implements a switch structure. The switch is a Java construct that says, "In the case of this, do that, and in the case of this, do that; otherwise, as a default, do this." This type of code construct is perfect for the main Android menu, as it usually has only five or six items.

Figure 7-20 shows the UserInterface.java code in the Eclipse editor in context with our previous two code blocks. In the figure, the new code is boxed. We will cover the top import statements, then the outer onOptionsItemSelected() method, and then its inner switch statement and programming logic for each button case statement and what it needs to do in the UI (switch images, background colors, and so on).

Java code to implement our menu functionality shown in the Eclipse IDE

Figure 7.20. Java code to implement our menu functionality shown in the Eclipse IDE

First are the import statements for the Android classes that we are going to use in our onOptionsItemSelected() method (see the top box in Figure 7-20):

  • Since we reference MenuItem in our onOptionsItemSelected() method, we need to import android.view.MenuItem.

  • Since we are going to switch image resources in our ImageView UI object, we also need to import android.widget.ImageView.

  • Since we are going to change our LinearLayout background color from black to white, we need to import android.widget.LinearLayout as well.

Remember that importing the class libraries that we are going to use in our Java code makes sure they are in memory when Eclipse needs to use them during the compilation of our Java code.

Next, let's examine our onOptionsItemSelected() code. First, we need to create references to our LinearLayout and ImageView objects, so that we can operate on these objects. This way, we can adjust their resource values to change our menu buttons' image and background color.

The first line creates a LinearLayout object called bkgr and sets it to the LinearLayout that is assigned the ID uilayout via the findViewById() method. The second line creates an ImageView object called image and sets it to the ImageView that is assigned the ID ImageView01 in the same way. These IDs can be seen in the main.xml file and tab, so you can check that everything matches up.

Finally, we have the Java switch statement. It starts with switch(item.getItemId()), which means "Decide between the following options (each case statement) based on the ID of the MenuObject that we named item. If nothing matches, just use the default action at the bottom of the statement decision tree list." The case statements work as follows:

  • The first case statement says, "In the case of the itemMenuItem with an ID of buttonone being passed, please set the imageImageView object's image resource to the 24-bit PNG image called image1 in the /drawable folder using the setImageResource() method."

  • The second case statement says, "In the case of the itemMenuItem with an ID of buttontwo being passed over, please set the imageImageView object's image resource to the 24-bit PNG image called image2 in the /drawable folder using the setImageResource() method."

  • The third case statement says, "In the case of the itemMenuItem with an ID of buttonthree being passed over, please set the bkgrLinearLayout object's background resource to the color resource called background2 in the /values/strings.xml resource using the setBackgroundResource() method."

  • The fourth case statement says, "In the case of the itemMenuItem with an ID of buttonfour being passed over, please set the bkgrLinearLayout object's background resource to the color resource called background in the /values/strings.xml resource using the setBackgroundResource() method."

  • The fifth case is left open for our next section, and thus the button does nothing at this point.

If none of the case statements match IDs passed over to operate on, then the default action is made, which is to pass over to the onOptionsItemSelected() method of the superclass.

Adding Dialogs

An Android dialog is always created as part of an activity, and is presented in the form of a small, gray pop-up window that appears on top of the current activity's UI. Android dims that UI so that it does not compete with the dialog box.

The Dialog class is used to create an interruption of your current activity in order to collect or relay information to your application's end user. Examples of uses for dialogs include alert notifications, end-user option selection, information data collection, date selection, time selection, task or processing progress bar monitoring, and so on.

Using Custom Dialog Subclasses

Four custom subclasses of the Dialog class are provided as part of the Android API:

  • AlertDialog

  • ProgressDialog

  • DatePickerDialog

  • TimePickerDialog

You can also subclass your own custom Dialog class (say, CustomDialog) so that it does exactly what you need it to do.

The general way to create a basic dialog within any given activity is via the onCreateDialog(int) method. Android uses this method to track the dialog created, which activity it belongs to, and its current state.

To display a dialog once it is created, you use the showDialog(int) method, specifying the number of the dialog you wish to display. To hide or dismiss a Dialog object, use the dismissDialog(int) method, and the Dialog object will be removed from memory and the application.

Here, we'll take a closer look at the most often used (and the recommended) Dialog class: AlertDialog. Android provides an easy and powerful way to construct alert dialogs with many features.

Displaying an Alert Dialog

The AlertDialog class provides a lot of built-in dialog features, such as a title, user message, up to three buttons, and a list of selectable items. You can even use check boxes and radio buttons in your list.

The AlertDialog works its magic via a dialog builder that provides a ready-made dialog code structure for you to create complicated dialogs via the AlertDialog.Builder class.

As shown in the boxed areas of Figure 7-21, there are four main parts to adding our AlertDialog to our existing Android application.

Java code for implementing our alert dialog builder in the Eclipse IDE

Figure 7.21. Java code for implementing our alert dialog builder in the Eclipse IDE

First, we add the import statements for the Android utilities we are going to leverage to provide our AlertDialog object:

import android.app.AlertDialog;
import android.content.DialogInterface;

Next, we create our AlertDialog.Builder object, which we name builder. This is a new (empty and initialized) AlertDialog.Builder object.

public boolean onOptionsItemSelected(MenuItem item) {
    LinearLayout bkgr = (LinearLayout)findViewById(R.id.uilayout);
    final ImageView image = (ImageView)findViewById(R.id.ImageView01);

    AlertDialog.Builder builder = new AlertDialog.Builder(this);

In order to work with the image object inside the builder dialog object that we are constructing, we need to add the keyword final to our declaration of this object variable (you'll see why in the next step). The final keyword is used for variables, methods, and classes. A final variable cannot be given a new value after it has been assigned one (although we can alter the variable object like any other object). A final method cannot be overridden. Also, a final class cannot be extended, and is thus in a sense protected from further programming modifications.

The preceding code basically says, "I want to declare an object named builder that is of the type AlertDialog.Builder, and I wish to set it equal to this new AlertDialog.Builder object that I am creating here. Therefore, please instantiate an empty AlertDialog.Builder object for me to define and fill with my own custom parameters."

After this has been declared, builder exists as an empty AlertDialog ready to fill with our own custom parameters. OK, on to the fun part and the third and major part of AlertDialog definition.

Here is the code to customize our dialog:

builder.setTitle("Pick an Image!")
      .setMessage("Please Select Image One or Image Two:")
      .setCancelable(false)
      .setPositiveButton("IMAGE 1", new DialogInterface.OnClickListener()
      {
            public void onClick(DialogInterface dialog, int id) {
                  image.setImageResource(R.drawable.image1);
            }
      })

      .setNegativeButton("IMAGE 2", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                  image.setImageResource(R.drawable.image2);
            }
       });

We work with the image object, which we know can't be reassigned a value because it is final. This is to deal with situations where the event listener is used after the onOptionsItemSelected() method has terminated. In this case, a non-finalimage variable would not be around to take a new assignment, whereas a final variable is frozen in memory for access at all times (of course, this may never happen, but Java was built this way just to be sure).

Notice in this block of code that sets our AlertDialog parameters (I am amazed that they did not offload AlertDialog parameters to an alert_dialog.xml file) that a new concept called method chaining is used. This allows a large number of parameters to be set without the builder object being explicitly typed before each dot-notation construct.

In method chaining, the first method is attached to its object with dot notation. In our example, it looks like this:

builder.setTitle("Pick an Image!")

The follow-on methods that set the other parameters are simply .setMessage(), .setCancelable(false), and so on.

I've formatted the preceding code for ease of reading. But to give you a little more grip on method chaining, the first three method calls could be rewritten as follows, illustrating the chain:

builder.setTitle("Pick an Image!").setMessage("Please Select...").setCancelable(false)

Also note that between contiguous methods, there is no semicolon at the end of these parameter setting lines of code. Semicolons are required on only the last and final method call—in this case, after .setNegativeButton() to end the builder definition.

Note

In this case, the order of the chained methods doesn't matter because each one returns an AlertDialog.Builder object with the new parameter set alongside all the other parameters that have been set so far. In other cases, the order of chaining matters. Android has been well designed to make chaining easy and convenient.

The code for setting the title, the message, and whether the Back button on the phone is able to cancel the dialog (in this case, it is not cancelable) is pretty straightforward here, so let's go over what is happening inside each button.

You can have up to three buttons in an AlertDialog object. These buttons are hard-coded into the Android operating system as follows:

  • PositiveButton

  • NeutralButton

  • NegativeButton

This explains the setPositiveButton() and setNegativeButton() methods shown in the preceding code.

The convention here is to use PositiveButton for one-button dialogs, PositiveButton and NegativeButton for two-button dialogs, and all three for three-button dialogs. The code inside the two buttons in our dialog is nearly identical, so let's go over what is happening inside the first button, IMAGE 1.

.setPositiveButton("IMAGE 1", new DialogInterface.OnClickListener()
      {
            public void onClick(DialogInterface dialog, int id) {
                  image.setImageResource(R.drawable.image1);
            }
      })

The setPositiveButton() method allows us to name the button IMAGE 1 and creates a new OnClickListener() implementation for the DialogInterface. Note that we declared android.content.DialogInterface in an import statement initially, and it is being used here to create a PositiveButton.

Inside the OnClickListener, we have a public method onClick(), which defines what will be done when the button is clicked. onClick() is passed a dialog object of type DialogInterface and an integer ID value that represents which of the buttons was clicked or the numerical order of the button that was clicked—both of which are what OnCLickListener wants to evaluate in the event the user clicks that button.

Inside this onClick container is where our code goes to change our ImageView object to the appropriate image resource. Since we have already done that in the menu code, we can simply copy the image.setImageResource(R.drawable.image1) code from down in our switch construct for ButtonOne.

Finally, down inside our switch statement, where before we had a placeholder comment, we can now display the dialog by calling the show() method of the builder object that we created earlier. This line of code could not be simpler:

builder.show();

Whenever the fifth menu button is clicked, our dialog will be shown. We can select between the two images, which will then be set on our screen appropriately.

Now, right-click your Chapter7 folder and select Run As...

Java code for implementing our alert dialog builder in the Eclipse IDE
Viewing our alert dialog in the emulator

Figure 7.22. Viewing our alert dialog in the emulator

Summary

With the exception of dialogs, Android allows us to put together our designs using XML, and to implement them with just a half-dozen lines of code is some instances, such as when creating a system options menu. This allows designers to get one step closer to the coding process.

In this chapter, we created an application that has all of the primary UI objects that can be used to construct an application:

  • ImageButtons allow us to create custom UI elements.

  • TextView and ImageView objects allow us to put relevant information on the screen.

  • Menu items allow us to use the Android Menu button to control our application.

  • Alert dialogs interface with our users to gather information or inform about decisions.

In the next chapter, you will learn how to add graphics to provide even more new media user experiences in your Android applications.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
98.82.120.188