Mobile Phone Handheld Hardware Hardware Rick Rogers John Lombardo O'Reilly Media, Inc. O'Reilly Media Android Application Development, 1st Edition11.2. ViewGroupsViewGroups are Views that contain child Views. Each
ViewGroup class embodies a different set of assumptions
about how to display its child Views. All ViewGroups descend from the
android.view.ViewGroup class. Layouts, which we'll
discuss later in the chapter, are a subset of ViewGroups. 11.2.1. Gallery and GridViewThe Gallery ViewGroup (Figure 11-4) displays multiple
items in a horizontally scrolling list. The currently selected item is
locked in the center of the screen. Any items that approach the edge of
the screen begin to fade, giving the user the impression that there may
be more items "around the corner." The user can scroll horizontally
through the items within the gallery. This ViewGroup is useful when you
want to present a large set of possible choices to the user without
using too much screen real estate. 
A GridView (Figure 11-5, shown later) is very
similar to a Gallery. Like a Gallery, the GridView displays many child
Views that the user can manipulate. But in contrast to a Gallery, which
is a one-dimensional list that the user can scroll horizontally, a
GridView is a two-dimensional array that the user can scroll
vertically. The Gallery and GridView
classes both descend from the AdapterView class, so
you need a subclass of Adapter to provide a standardized way to access
the underlying data. Any class that implements the Adapter class must implement the following
abstract functions from that class:
int getCount Returns the number of items in the data set represented by
the Adapter.
Object getItem(int
position) Returns the object in the Adapter function (Adapter
class) at the given position.
long getItem(int
position) Returns the row ID within the Adapter of the object at the given
position.
View getView(int position, View
convertView, ViewGroup parent) Returns a View object that will display the data in the
given position in the data set.
The ApiDemos application's views.Gallery1.java file shows off the
Gallery ViewGroup nicely. The demo displays a variety of images for the
user to select, and when the user does select one, the image's index
number briefly appears as toast. The ApiDemos application also includes two example GridView
Activities that show how to use the GridView. We will not examine the
GridView here, because the Gallery example is so similar. Example 11-4 shows how to
use a Gallery ViewGroup. Example 11-4 shows the XML layout
file (gallery_1.xml). Example 11-4. Layout file for Gallery example<?xml version="1.0" encoding="utf-8"?>
<Gallery xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/> |
Here are some of the highlights of the layout code: 
Now we'll turn our attention to the Java implementation, Gallery1.java, shown in Example 11-5. We've modified the code
from ApiDemos slightly to remove some features that do not add to our
understanding of the Gallery ViewGroup. Example 11-5. Java for Gallery: Gallery1.javapublic class Gallery1 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery_1);
// Reference the Gallery view
Gallery g = (Gallery) findViewById(R.id.gallery);
// Set the adapter to our custom adapter (below)
g.setAdapter(new ImageAdapter(this));
// Set a item click listener, and just Toast the clicked position
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
} |
Here are some of the highlights of the code: In Example 11-5, the
setAdapter function tells the
Gallery object to use the ImageAdapter object as its Adapter. Example 11-6 defines our ImageAdapter class. This
ImageAdapter implements all of the abstract functions
required in its base class, BaseAdapter. For the
simple case of this demo, picture resources represent the data that the
Gallery view is displaying. An integer array, mImageIds, contains the resource IDs of the
picture resources. Example 11-6. Java for Gallery's Adapter public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private Integer[] mImageIds = {
R.drawable.gallery_photo_1,
R.drawable.gallery_photo_2,
R.drawable.gallery_photo_3,
R.drawable.gallery_photo_4,
R.drawable.gallery_photo_5,
R.drawable.gallery_photo_6,
R.drawable.gallery_photo_7,
R.drawable.gallery_photo_8
};
public ImageAdapter(Context c) {
mContext = c;
TypedArray a = obtainStyledAttributes(android.R.styleable.Theme);
mGalleryItemBackground = a.getResourceId(
android.R.styleable.Theme_galleryItemBackground, 0);
a.recycle();
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
// The preferred Gallery item background
i.setBackgroundResource(mGalleryItemBackground);
return i;
}
}
} |
Here are some of the highlights of the code: 11.2.2. ListView and ListActivityListView is similar to Gallery, but uses a vertically scrolling list
in place of Gallery's horizontally scrolling list. To create a ListView
that takes up the entire screen, Android provides the
ListActivity class (Figure 11-6). The ApiDemos application includes many examples of ListActivity.
The simplest is the List1 class,
which displays a huge number of cheese names in a list. The cheese names
are kept in a simple String array
(who knew there were that many cheese varieties!): public class List1 extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Use an existing ListAdapter that will map an array
// of strings to TextViews
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mStrings));
}
private String[] mStrings = {
"Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance",
"Ackawi",
"Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag",
"Airedale",
...
Filling the ListView in the ListActivity is a simple matter of
calling setListAdapter and passing it
an ArrayAdapter that contains a
reference to the list of strings. 11.2.3. ScrollViewA ScrollView is a container for another View that lets the user scroll
that View vertically (a scrollbar is optional). A ScrollView often
contains a LinearLayout, which in turn contains the Views that make up
the form. Don't confuse ScrollView with ListView. Both Views present the
user with a scrollable set of Views, but the ListView is designed to
display a set of similar things, such as the cheeses in the previous
section. The ScrollView, on the other hand, allows an arbitrary View to
scroll vertically. The Android documentation warns that one should never
house a ListView within a ScrollView, because that defeats the
performance optimizations of a ListView. A ScrollView is a FrameLayout, which means that it can have only
one child View. The most popular View for this purpose is a
LinearLayout. The following layout code from ApiDemos, scroll_view_2.xml, shows how to set up a
ScrollView. The XML layout resource is sufficient; this example includes
no extra Java code: <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:id="@+id/layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/scroll_view_2_text_1"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/scroll_view_2_button_1"/>
</LinearLayout>
</ScrollView>Here are some of the highlights of the code: 

11.2.4. TabHostMost modern UIs provide an interface element that lets the
user flip through many pages of information quickly using tabs, with
each "screen" of information available when its tab is pressed.
Android's option is the TabHost View. Figures Figure 11-7 through Figure 11-10 show how it operates. 

Android enables the developer to choose between three different
approaches for setting the tab's content. The developer can: Set the content of a tab to an Intent. Figures Figure 11-7 and Figure 11-9 use this method. Use a TabContentFactory to create the tab's content on-the-fly. Figure 11-8 uses this
method. Retrieve the content from an XML layout file, much like that
of a regular Activity. Figure 11-10 uses this
method.
We'll examine each of these possibilities using a modified
Activity from the ApiDemos application. The fourth tab is not part of
the ApiDemos, but combines some other TabHost demonstration Activities
in ApiDemos. Let's start by looking at the tabs4.xml layout file (Example 11-7). Example 11-7. Layout file for TabHost (tabs4.xml)<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/view4"
android:background="@drawable/green"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/tabs_4_tab_4"/>
</FrameLayout> |
Here are some of the highlights of the code: And now we'll dissect the Java code that produces the tabs (Example 11-8). Example 11-8. Java for TabHostpublic class Tabs4 extends TabActivity implements TabHost.TabContentFactory {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TabHost tabHost = getTabHost();
LayoutInflater.from(this).inflate(R.layout.tabs4, tabHost.getTabContentView(),
true);
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("intent")
.setContent(new Intent(this, List1.class)));
tabHost.addTab(tabHost.newTabSpec("tab2")
.setIndicator("factory",
getResources().getDrawable(R.drawable.star_big_on))
.setContent(this));
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("destroy")
.setContent(new Intent(this, Controls2.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
tabHost.addTab(tabHost.newTabSpec("tab4")
.setIndicator("layout")
.setContent(R.id.view4));
}
public View createTabContent(String tag) {
final TextView tv = new TextView(this);
tv.setText("Content for tab with tag " + tag);
return tv;
}
} |
Here are some of the highlights of the code:
|