Putting It on My

The general Android philosophy is to keep activities short and sweet. If there is more information than can reasonably fit on one screen, albeit perhaps with scrolling, then it most likely belongs in another activity kicked off via an Intent, as will be described Chapter 24. However, that can be complicated to set up. Moreover, sometimes there legitimately is a lot of information that needs to be collected to be processed as an atomic operation.

In a traditional UI, you might use tabs to accomplish this end, such as a JTabbedPane in Java/Swing. In Android, you now have an option of using a TabHost container in much the same way—a portion of your activity's screen is taken up with tabs which, when clicked, swap out part of the view and replace it with something else. For example, you might have an activity with a tab for entering a location and a second tab for showing a map of that location.

Some GUI toolkits refer to "tabs" as being just the things a user clicks on to toggle from one view to another. Some toolkits refer to "tabs" as being the combination of the clickable button-ish element and the content that appears when that tab is chosen. Android treats the tab buttons and contents as discrete entities, so we will call them "tab buttons" and "tab contents" in this section.

The Pieces

There are a few widgets and containers you need to use in order to set up a tabbed portion of a view:

• TabHost is the overarching container for the tab buttons and tab contents.

• TabWidget implements the row of tab buttons, which contain text labels and optionally contain icons.

• FrameLayout is the container for the tab contents; each tab content is a child of the FrameLayout.

This is similar to the approach that Mozilla's XUL takes. In XUL's case, the tabbox element corresponds to Android's TabHost, the tabs element corresponds to TabWidget, and tabpanels corresponds to the FrameLayout.

The Idiosyncrasies

There are a few rules to follow, at least in this milestone edition of the Android toolkit, in order to make these three work together:

• You must give the TabWidget an android:id of @android: id/tabs.

• You must set aside some padding in the FrameLayout for the tab buttons.

• If you wish to use the TabActivity, you must give the TabHost an android:id of @android:id/tabhost.

TabActivity, like ListActivity, wraps a common UI pattern (activity made up entirely of tabs) into a pattern-aware activity subclass. You do not necessarily have to use TabActivity—a plain activity can use tabs as well.

With respect to the FrameLayout padding issue, for whatever reason, the TabWidget does not seem to allocate its own space inside the TabHost container. In other words, no matter what you specify for android:layout height for the TabWidget, the FrameLayout ignores it and draws at the top of the overall TabHost. Your tab contents obscure your tab buttons. Hence, you need to leave enough padding (via android: paddingTop) in FrameLayout to "shove" the actual tab contents down beneath the tab buttons.

In addition, the TabWidget seems to always draw itself with room for icons, even if you do not supply icons. Hence, for this version of the toolkit, you need to supply at least 62 pixels of padding, perhaps more depending on the icons you supply.

For example, here is a layout definition for a tabbed activity, from Fancy/Tab:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout width="fill parent" android:layout height="fill parent"> <TabHost android:id="@+id/tabhost" android:layout width="fill parent" android:layout height="fill parent"> <TabWidget android:id="@android:id/tabs" android:layout width="fill parent" android:layout height="wrap content"

<FrameLayout android:id="@android:id/tabcontent" android:layout width="fill parent" android:layout height="fill parent" android:paddingTop="62px"> <AnalogClock android:id="@+id/tab1" android:layout width="fill parent" android:layout height="fill parent" android:layout centerHorizontal="true"

<Button android:id="@+id/tab2" android:layout width="fill parent" android:layout height="fill parent" android:text="A semi-random button"

</FrameLayout> </TabHost> </LinearLayout>

Note that the TabWidget and FrameLayout are immediate children of the TabHost, and the FrameLayout itself has children representing the various tabs. In this case, there are two tabs: a clock and a button. In a more complicated scenario, the tabs are probably some form of container (e.g., LinearLayout) with their own contents.

0 0

Post a comment