<TextView android:text="#440000"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow>
<View
android:layout_height="80px"
android:background="#884400" />
<TextView android:text="#884400"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow>
<View
android:layout_height="80px"
android:background="#aa8844" />
<TextView android:text="#aa8844"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow>
<View
android:layout_height="80px"
android:background="#ffaa88" />
<TextView android:text="#ffaa88"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow>
<View
android:layout_height="80px"
android:background="#ffffaa" />
<TextView android:text="#ffffaa"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow>
<View
android:layout_height="80px"
android:background="#ffffff" />
<TextView android:text="#ffffff"
android:paddingLeft="4px"
android:layout_gravity="center_vertical" />
</TableRow>
</TableLayout>
</ScrollView>
Without the ScrollView
, the table would take up at least 560 pixels (7 rows at 80 pixels each, based on the View
declarations). There may be some devices with screens capable of showing that much information, but many will be smaller. The ScrollView
lets us keep the table as is, but present only part of it at a time.
On the stock Android emulator, when the activity is first viewed, you see what’s shown in Figure 7-8.
Figure 7-8. The ScrollViewDemo sample application
Notice how only five rows and part of the sixth are visible. By pressing the up/down buttons on the directional pad, you can scroll up and down to see the remaining rows. Also note how the right side of the content gets clipped by the scrollbar — be sure to put some padding on that side or otherwise ensure your own content does not get clipped in that fashion.
CHAPTER 8
Using Selection Widgets
In Chapter 6, you saw how fields could have constraints placed upon them to limit possible input, such as numeric-only or phone-number-only. These sorts of constraints help users “get it right” when entering information, particularly on a mobile device with cramped keyboards.
Of course, the ultimate in constrained input is to select a choice from a set of items, such as the radio buttons seen earlier. Classic UI toolkits have listboxes, comboboxes, drop-down lists, and the like for that very purpose. Android has many of the same sorts of widgets, plus others of particular interest for mobile devices (e.g., the Gallery
for examining saved photos).
Moreover, Android offers a flexible framework for determining what choices are available in these widgets. Specifically, Android offers a framework of data adapters that provide a common interface to selection lists ranging from static arrays to database contents. Selection views — widgets for presenting lists of choices — are handed an adapter to supply the actual choices.
Adapting to the Circumstances
In the abstract, adapters provide a common interface to multiple disparate APIs. More specifically, in Android’s case, adapters provide a common interface to the data model behind a selection-style widget, such as a listbox. This use of Java interfaces is fairly common (e.g., Java/Swing’s model adapters for JTable
), and Java is far from the only environment offering this sort of abstraction (e.g., Flex’s XML data-binding framework accepts XML inlined as static data or retrieved from the Internet).
Android’s adapters are responsible for providing the roster of data for a selection widget plus converting individual elements of data into specific views to be displayed inside the selection widget. The latter facet of the adapter system may sound a little odd, but in reality it is not that different from other GUI toolkits’ ways of overriding default display behavior. For example, in Java/Swing, if you want a JList
-backed listbox to actually be a checklist (where individual rows are a checkbox plus label, and clicks adjust the state of the checkbox), you inevitably wind up calling setCellRenderer()
to supply your own ListCellRenderer
, which in turn converts strings for the list into JCheckBox
-plus-JLabel
composite widgets.
Using ArrayAdapter
The easiest adapter to use is ArrayAdapter
— all you need to do is wrap one of these around a Java array or java.util.List
instance, and you have a fully-functioning adapter:
String[] items={this, is, a,
really, silly, list};
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items);
The ArrayAdapter
constructor takes three parameters:
• The Context
to use (typically this will be your activity instance)
• The resource ID of a view to use (such as a built-in system resource ID, as previously shown)
• The actual array or list of items to show
By default, the ArrayAdapter
will invoke toString()
on the objects in the list and wrap each of those strings in the view designated by the supplied resource. android.R.layout.simple_list_item_1
simply turns those strings into TextView
objects. Those TextView
widgets, in turn, will be shown the list or spinner or whatever widget uses this ArrayAdapter
.
You can subclass ArrayAdapter
and override getView()
to “roll your own” views:
public View getView(int position, View convertView,
ViewGroup parent) {
if (convertView==null) {
convertView = new TextView(this);
}
convertView.setText(buildStringFor(position));