android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RadioButton android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rock" />
<RadioButton android:id="@+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scissors" />
<RadioButton android:id="@+id/radio3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Paper" />
</RadioGroup>
Figure 6-6 shows the result using the stock Android-generated Java for the project and this layout.
Figure 6-6. The RadioButtonDemo sample application
Note that the radio button group is initially set to be completely unchecked at the outset. To pre-set one of the radio buttons to be checked, use either setChecked()
on the RadioButton
or check()
on the RadioGroup
from within your onCreate()
callback in your activity.
It’s Quite a View
All widgets, including the ones previously shown, extend View, and as such give all widgets an array of useful properties and methods beyond those already described.
Useful Properties
Some of the properties on View most likely to be used include:
• Controls the focus sequence:
• android:nextFocusDown
• android:nextFocusLeft
• android:nextFocusRight
• android:nextFocusUp
• android:visibility
, which controls whether the widget is initially visible
• android:background
, which typically provides an RGB color value (e.g., #00FF00
for green) to serve as the background for the widget
Useful Methods
You can toggle whether or not a widget is enabled via setEnabled()
and see if it is enabled via isEnabled()
. One common use pattern for this is to disable some widgets based on a CheckBox
or RadioButton
selection.
You can give a widget focus via requestFocus()
and see if it is focused via isFocused()
. You might use this in concert with disabling widgets as previously mentioned, to ensure the proper widget has the focus once your disabling operation is complete.
To help navigate the tree of widgets and containers that make up an activity’s overall view, you can use:
• getParent()
to find the parent widget or container
• findViewById()
to find a child widget with a certain ID
• getRootView()
to get the root of the tree (e.g., what you provided to the activity via setContentView()
)
CHAPTER 7
Working with Containers
Containers pour a collection of widgets (and possibly child containers) into specific layouts you like. If you want a form with labels on the left and fields on the right, you will need a container. If you want OK and Cancel buttons to be beneath the rest of the form, next to one another, and flush to the right side of the screen, you will need a container. From a pure XML perspective, if you have multiple widgets (beyond RadioButton
widgets in a RadioGroup
), you will need a container just to have a root element to place the widgets inside.
Most GUI toolkits have some notion of layout management, frequently organized into containers. In Java Swing, for example, you have layout managers like BoxLayout
and containers that use them (e.g., Box
). Some toolkits, such as XUL and Flex, stick strictly to the box model, figuring that any desired layout can be achieved through the right combination of nested boxes.
Android, through LinearLayout
, also offers a box model, but in addition it supports a range of containers providing different layout rules. In this chapter we will look at three commonly used containers: LinearLayout
(the box model), RelativeLayout
(a rule-based model), and TableLayout
(the grid model), along with ScrollView
, a container designed to assist with implementing scrolling containers. In the next chapter we will examine some more-esoteric containers.
Thinking Linearly
As noted already, LinearLayout
is a box model — widgets or child containers are lined up in a column or row, one after the next. This works similarly to FlowLayout
in Java Swing, vbox
and hbox
in Flex and XUL, etc.
Flex and XUL use the box as their primary unit of layout. If you want, you can use LinearLayout
in much the same way, eschewing some of the other containers. Getting the visual representation you want is mostly a matter of identifying where boxes should nest and what properties those boxes should have, such as alignment vis-à-vis other boxes.
Concepts and Properties
To configure a LinearLayout
, you have five main areas of control besides the container’s contents: the orientation, the fill model, the weight, the gravity, and the padding.
Orientation
indicates whether the LinearLayout
represents a row or a column. Just add the android:orientation
property to your LinearLayout
element in your XML layout, setting the value to be horizontal
for a row or vertical
for a column.
The orientation can be modified at runtime by invoking setOrientation()
on the LinearLayout
, supplying it with either HORIZONTAL
or VERTICAL
.
Let’s imagine a row of widgets, such as a pair of radio buttons. These widgets have a “natural” size based on their text. Their combined sizes probably do not exactly match the width of the Android device’s screen — particularly since screens come in various sizes. We then have the issue of what to do with the remaining space.
All widgets inside a LinearLayout
must supply android:layout_width
and android:layout_height
properties to help address this issue. These properties’ values have three flavors:
• You can provide a specific dimension, such as 125px
, to indicate the widget should take up exactly 125 pixels.
• You can provide wrap_content
, which means the widget should fill up its natural space unless that is too big, in which case Android can use word wrap as needed to make it fit.
• You can provide fill_parent
, which means the widget should fill up all available space in its enclosing container after all other widgets are taken care of.
The latter two flavors are the most common, as they are independent of screen size, allowing Android to adjust your view to fit the available space.