The RelativeLayout is the mack daddy of the Android screen layout system. It allows you to position all your child views in relation to either the parent (the layout itself) or any other child view within the layout. Let’s take a look at one in action.
Here’s the now familiar image and button arrangement in the photo viewer, but with a RelativeLayout (Figure 3.10).
There are a few slight measurement differences between this image and the one produced with the LinearLayout. This one is also missing the gray background behind the buttons, which I’ll show you how to add shortly.
Take a look at the XML layout that produced the image in Figure 3.10.
<?xml version=”1.0” encoding=”utf-8”?>
<RelativeLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
FIGURE 3.10 Designing the same screen, except with the RelativeLayout.
ptg7794906
<Button
android:id=”@+id/prev”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:padding=”15dip”
android:text=”@string/prev_string”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”
/>
<Button
android:id=”@+id/next”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:padding=”15dip”
android:text=”@string/next_string”
android:layout_alignParentRight=”true”
android:layout_alignParentTop=”true”
/>
<TextView
android:id=”@+id/text_view”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:gravity=”center”
android:layout_toRightOf=”@id/prev”
android:layout_toLeftOf=”@id/next”
android:layout_alignParentTop=”true”
android:layout_centerHorizontal=”true”
android:layout_alignBottom=”@id/prev”
LAYOUT MANAGEMENT 91
ptg7794906 android:text=”The Golden Gate Bridge”
/>
<ImageView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_below=”@id/text_view”
android:gravity=”center”
android:id=”@+id/main_image”
android:src=”@drawable/bridge”
/>
</RelativeLayout>
In this layout code, you see the same view components that made up the Linear Layout except, with the relative version, there’s no need for a second, nested layout.
The mechanics to each member of a RelativeLayout can be more complex than its linear cousin, so I’ll endeavor to break down all four pieces of this screen one at a time.
The <RelativeLayout> declaration contains only enough information to tell the layout to fill the entire screen. All information on how to lay out the screen is found in the child elements. Here’s the first one:
<Button
android:id=”@+id/prev”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:padding=”15dip”
android:text=”@string/prev_string”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”
/>
ptg7794906 The first view, which declares the Prev button, initially declares its ID in the
android:id line. The Prev button needs an ID so you can assign a click listener to it in the activity code. The layout height and width declarations simply tell the view to make it large enough to accommodate all the content (in this case, the
“prev” text and a little padding).
The padding declaration tells the system to push the boundaries for the button out from the smallest required space for the text. In this case, android:padding=”15dip”
tells the system to measure the required space for the “prev” text and then 15 more device-independent pixels to the outer boundary of the view. As a general rule, it’s always good to pad your buttons between 10 and 20 dip (depending on screen and text size). This gives them a little more space to be recognized as buttons, and it also gives people with large fingers a chance of actually hitting the view.
Now come the parts that tell the system where inside the layout object to place the button. The attribute android:layout_alignParentLeft=”true” tells Android to align the left edge of the view with the left edge of the parent’s bound-ing rectangle. In this case, it’s the left edge of the screen. The android:layout_
alignParentTop=”true” attribute does the same thing except with respect to the top of the layout object (in this case, the top of the application’s available space).
If you don’t specify any layout parameters, views will default to the upper-left corner of the layout object. This code example declares these views for explana-tion purposes.
Now that the Prev button is in place, you’re ready to move on. Here’s the relevant XML for the Next button:
ptg7794906 The Next button is nearly identical to the Prev button except for the ID (required
to set up a click listener in the activity), the text displaying on the button (“next”), and the android:layout_alignParentRight=”true” attribute (to lock it to the right side of the layout object—and thus the right side of the screen—instead of the left). Here’s the code for the title:
<TextView
android:id=”@+id/text_view”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_toRightOf=”@id/prev”
android:layout_toLeftOf=”@id/next”
android:layout_alignParentTop=”true”
android:layout_centerHorizontal=”true”
android:layout_alignBottom=”@id/prev”
android:text=”The Golden Gate Bridge”
android:gravity=”center”
/>
In this text view, things start to get a little more interesting. Again, the ID, height, and width are things you’ve seen before, but you need to change the title text as the images change. As the image changes, you’ll need an ID so the activity can change the name of the picture displayed above it.
android:layout_toRightOf=”@id/prev” tells the layout to align the left edge of the text view with the right edge of the Prev button. android:layout_toLeftOf=
”@id/next” tells the right edge of the text view to align with the left-most edge of the Next button. The android:gravity=”center” attribute tells the text to center itself within any extra available space. This will center it vertically (so it doesn’t stick to the top of the screen) and horizontally (so it doesn’t stick against the left-most button).
ptg7794906 This technique of centering a view in the space between two objects is one I use
frequently in my Android work, and it’s a good way to eat up extra space caused by small and large fluctuations in screen size. That is to say, the text in the center of the buttons will float, centered, within any available screen space you might get when using a larger screen than the one you’re designing.
ADDING THAT GRAY BACKGROUND
So, you might be asking, the LinearLayout example has a gray background; if the RelativeLayout is so amazing, why doesn’t it have one as well? First, stop asking your book questions; you’ll look a little odd in public. Second, I withheld the back-ground because I wanted to show you how easy it is to add it. I’ve placed the XML required to add the background in the following code. Take a second to look it over:
<!-- This is the top level layout -->
<RelativeLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
<View
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_alignParentLeft=”true”
android:layout_alignParentRight=”true”
android:layout_alignParentTop=”true”
android:layout_alignBottom=”@id/next”
android:background=”#ff222222”
/>
<!--Rest of the screen goes here -->
</RelativeLayout>
LAYOUT MANAGEMENT 95
ptg7794906 I want the gray box to be drawn behind the button bar, so I placed it as the first
view in the layout. Android draws the view stack in the order they’re declared. So, were I to incorrectly place the listed XML below the button and text declarations, you’d see only the gray bar covering over both the text and the buttons.
With that, you’ve successfully added a gray background and brought the Relative Layout version of this view into parity with the earlier LinearLayout demonstra-tion. The RelativeLayout can handle more complex displays without requiring other nested layouts. It also can, if you’re smart about it, handle changes in screen size, as shown by having the image’s name float between the buttons no matter how far apart they get.
ptg7794906
WRAPPING UP
Throughout this chapter, you’ve come to understand the fundamental building blocks that make up Android’s UI. While I haven’t yet had time to show you any of these particular classes in much depth, together we’ve laid the groundwork for more serious chapters to come. In this way I can dive deep into text views (yes, we will) without worrying that you’ll not know how to arrange them next to an image or make them respond to click events.
This concludes the overview of displaying information to users. You should be comfortable building and changing basic user interfaces through Java and Android’s XML layout system. If you didn’t skip any sections, you’ll also be able to extend existing built-in views to make Android do exactly your bidding. Next you’ll take a break from drawing things on screens and look at how to acquire data for your pretty user interfaces.
WRAPPING UP 97
ptg7794906