Getting Under the Hood

You'll now tinker under the hood and kick the tires of Android's widgets. You'll take a basic look at some of the core pieces, many of which you've explored in XML form. As in previous examples, for the sake of explanation, I'll keep it basic. It should be easy to apply what I've discussed here to the more complicated aspects of UI layout. In later, more advanced examples, you'll get more into other Android widgets. In the following example, I've taken pains to make sure you use little to none of the XML elements you relied on previously. It should give you a chance to get a good handle on non-XML layout, but keep in mind, practically, you'd have to be crazy to do all your user interface screens this way.

The Main Menu

Nearly all mobile applications, at least at the time of publication, begin with a graphical main menu. This graphical screen directs users to the various functionality of the mobile application. Because the concept of a

"main menu" is so universal to the mobile application experience, it makes for an excellent and practical case study. Your objective, in this example, is to put together a simple and functional main menu. For the sake of comparison, you'll use another linear layout to put everything together. The example will be built in three major stages:

1. Layout: You'll arrange all the entries of your main menu correctly on the screen. Granted, this will use only a fraction of Android's massive screen real estate. But most application menus will use large graphics and take up significantly more space.

2. Focus: You'll need to set up a focus structure so that users can move through the elements. As the focus shifts, you'll have to adjust the colors of each menu element.

3. Select events: Finally, you'll need to set up a listener so that when an element is selected or clicked, you're informed and can take the appropriate action based on the item selected.

When you've finished all three of these tasks, you should have the framework to build the primary entry screen of about 80 percent of all mobile applications. Although not entirely practical (being that I've used exactly zero XML), it is an excellent demonstration of how to get things done in a custom runtime-driven way. As you add more functionality to your "socially awkward" application, you'll fill out this main menu more completely.

Laying Out, Java-Style

The first step in the simple main menu is getting all your menu elements on the screen. As I mentioned earlier, you'll be using a linear layout to accomplish it. You'll need to do all this before the application draws for the first time, so it'll have to be in the onCreate method of the new MainMenu activity. (Refer to Chapter 1 if you've lost track of how to create and plug in a new activity.) Code Listing 3-2 shows what its instantiation and configuration looks like.

Code Listing 3-2. Creating a Layout Object in the onCreate Method

LinearLayout layout = new LinearLayout(this); layout.setBackground(R.drawable.general bg); layout.setOrientation(LinearLayout.VERTICAL); layout.setLayoutParams(

new LayoutParams(LayoutParams.FILL PARENT, LayoutParams. FILL_PARENT)); setContentView(layout);

After what you've been through thus far, this, conceptually, should seem familiar. You'll set the background using an image in the /res/drawable/ folder, set the linear layout orientation to vertical, and set the LayoutParams to fill the parent. (The parent, in this case, is the activity, which controls the full screen.) Layout parameters, at their base, must define the height and width of a given widget. As you'll probably find out later, trying to place a widget into a ViewGroup before its layout parameters are set will throw an exception. However, now that you have a layout object to fill, you can start building out the screen.

Adding a Title

Next, add a simple title, which will be centered, at the top of your main menu screen. Code Listing 3-3 shows the block of code you'll need for it.

Code Listing 3-3. Adding the Title

TextView title = new TextView(this); title.setText(R.string.man menu title); title.setLayoutParams(

new LinearLayout.LayoutParams( LinearLayout.LayoutParams. FILL_PARENT, LayoutParams. WRAP_CONTENT)); title.setAlignment(Alignment.ALIGN_CENTER);

layout.addView(title);

Create the text object, and set the text from the

/res/values/strings.xml. I know I said I wouldn't use any XML, but

I'm afraid I may have fibbed about that bit. In production, you'll want to move all your strings to this location rather than defining them in code. If your clients are like mine, you won't want to pull out your source editor and recompile every time they want to change the wording on one of the screens.

Now that you have a title, it's time to add the more interesting and active menu elements.

Laying Out Menu Entries

Now you'll add the individual menu elements. Because this is going to be fairly repetitive after the first one, I'll insert and explain the first element but leave you to your own devices for the rest. Feel free to grab the full project at the Apress site to see the rest of the menu items. Again, you'll fill in more of them as you progress through the rest of the Android essentials. Code Listing 3-4 shows the code to add an individual menu item.

Code Listing 3-4. Adding a Menu Item

TextView ItemOne = new TextView(this); ItemOne.setFocusable(true); ItemOne.setText("Login Screen"); ItemOne.setTextColor(Color.WHITE ); ItemOne.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT,

LayoutParams. WRAP_CONTENT));

//Give the menu item an ID for tracking reasons. //The ID is a static int defined locally to the class ItemOne.setId(IdOne); //Add it to our linear layout layout.addView(ItemOne);

Gosh, you probably think after reading the code carefully, this looks almost like the title you've already added. You're exactly right, how clever of you. The heavy lifting of denoting when an object is in focus and when it's been selected has yet to come, so don't get too cocky yet. Here are the two differences between the previous menu item and previously listed title text:

■ You need to tell the Textview that it can accept focus by calling the setFocusable method.

■ The menu listing item will need an ID so you can distinguish it from the rest of the menu elements in your selection handler.

As I mentioned briefly, whenever adding a widget to a viewGroup, the LayoutParams object must specifically be the object defined within that view group. For example, in the previous setLayoutParams method call, you must pass in a LinearLayout.LayoutParams object. You must pass in the correct subclassed layout parameter, or Android will throw an exception at you during runtime.

As I said before, to make the menu, I'll add two more text elements almost exactly like the previous listing. For the sake of expediency, I won't list them here. Be sure to refer to the full project to satisfy your curiosity. Now that you have all your menu items in place, it's time to modify them when they receive or lose focus.

Focus Young Grasshopper

To handle focus change events, you have to create an implementation of the OnFocusChangeListener abstract class. The example's version, defined locally within the MainMenu activity class, will look like Code Listing 3-5.

Code Listing 3-5. Creating a Focus Listener

OnFocusChangeListener focusListener = new OnFocusChangeListener()

public void onFocusChanged(View v, boolean hasFocus) {

adjustTextColor(v, hasFocus);

private void adjustTextColor(View v, boolean hasFocus) {

//Dangerous cast. Be sure you are //listening only to TextView focus changes // or this could go horribly wrong. TextView t = (TextView)v; if(hasFocus)

t.setTextColor(Color.RED);

else t.setTextColor(Color.WHITE);

In addition, you have to add the following line corresponding to each selectable element in the menu to attach the focus change listener object:

ItemOne.setOnFocusChangeListener(focusListener);

With the listener in place, you'll now be notified each time one of your menu elements gains or loses focus. In more advanced main menus, this method would be the place to add image shifts, animations, 3D explosions, or other whiz-bang graphical effects. In this example, you'll have to settle for just changing the text color. Now that the user can tell, through the color change, which menu item is highlighted, you'll need to react when they press the center key to select an item.

Tip It's possible to set the focused, unfocused, and selected color of a TextView by using the setTextColor (ColorStateList colors) method, which is a simpler way of implementing a text-based main menu. There are always many ways to accomplish a goal in a good IDE; I've simply selected the more versatile (because I hope your applications move beyond text menus). For more information on using setTextColor, see the Android documentation at http://code.google.com/android/ reference/android/widget/TextView.html#setTextColor(int) .

Click and Select Events

You've already seen how to register for onclick events in the login screen, so you should be able to breeze through this section without trouble. Code Listing 3-6 shows the example code to grab select events.

Code Listing 3-6. Adding a Selection Listener

OnClickListener clickListener = new OnClickListener() {

public void onClick(View v) {

String text = "You selected Item: ";

caseIdOne:

text += "1"; startActivity(

new Intent(MainMenu.this, Login.class)); break; caseIdTwo:

text += "2"; startActivity( new Intent(

"com.apress.example.CUSTOM_VIEW")); break; caseIdThree:

//We'll get to the following line in a bit status.setText(text);

The previous switch statement is the reason for calling setID back when you were originally creating and laying out the TextView widgets. When a menu item is selected or clicked by the pointer, the onClick function is called, and the corresponding view is passed in as a parameter. You will examine the ID of the view passed in to determine which menu item was selected. This allows you to take the appropriate action for the menu selected. In this way, you can switch to the previously defined login screen and your soon-to-be-written custom view with the startActivity method call.

There's still one small step left, and if you look at the bottom of the onCreatefuction in the sample code, you'll spot it. You need to add a click listener to the view. Here's the line that should be run while you build up the widget list:

ItemOne.setOnClickListener(clickListener);

Looking Back

Reviewing the Java-driven main menu, you've accomplished several important things.

First, you performed the layout functionally previously only through XML files. Although not entirely practical to do by hand, it does give you the tools to change and customize the XML views while your application is running.

Second, you registered for focus change events for all your menu items. When the focus change listener was called, you changed the color of the focused item to highlight it. In practical use, there are more efficient ways of accomplishing the same thing, but I'm assuming you'd want to substitute changing text colors for something more, shall we say, extravagant.

Third, you learned how to listen for and react to select events, discern which item was selected, and take the appropriate action based on that selection.

Again, looking over all the code required to lay widgets out on the screen by hand is fairly prohibitive, but using the tools you've just learned, you could modify, enhance, and customize how a menu or list works based on data and user preference while the app is running. If, however, you need to get even more specialized with how you draw to the screen, you'll need a less subtle and more code-heavy approach.

iPhone and iPad App Cash

iPhone and iPad App Cash

Discover how a single application could generate $1000's of dollars, instantly. The simple, low cost system for outsourcing app development to freelancers. How to quickly evaluate applications so you can create a high profit one of your very own. The fastest way to leverage the popularity of iPhone and iPad apps to skyrocket your income. Top methods for promoting your application for maximum exposure.

Get My Free Ebook


Post a comment