Android 定制 Tabs

Android Tabs

Wanting to change the default TabWidget look and feel for Android?  In this tutorial, we will investigate a few different ways to customize your app's tabs.With Android SDK 1.6 and above, the SDK allows you to set a View as the tab instead of just text and an icon.  We use be using that technique to create custom looking tabs.

Step 1: Create a layout

First off, let's create an XML layout called main.xml that contains a TabHost andTabWidget.

01 <?xmlversion="1.0"encoding="utf-8"?>
02 <TabHostxmlns:android="http://schemas.android.com/apk/res/android"
03     android:id="@android:id/tabhost"android:layout_width="fill_parent"
04     android:layout_height="fill_parent">
05     <LinearLayoutandroid:orientation="vertical"
06         android:layout_width="fill_parent"android:layout_height="fill_parent">
07         <TabWidgetandroid:id="@android:id/tabs"
08             android:layout_width="fill_parent"android:layout_height="wrap_content"/>
09         <FrameLayoutandroid:id="@android:id/tabcontent"
10             android:layout_width="fill_parent"android:layout_height="fill_parent">
11         </FrameLayout>
12     </LinearLayout>
13 </TabHost>

Step 2: Write the Activity Code

Once we have a layout, we need to create our main Activity.  For this, you can have your class extendTabActivity.  However, if the contents of one of the tabs is a MapView, you will need extend MapActivity.

Let's create a class called CustomTabActivity and have it extend TabActivity.

In the onCreate() method, we need to set the content to our XML layout and extract theTabHost object.

1 setContentView(R.layout.main);
2 mTabHost = (TabHost) findViewById(android.R.id.tabhost);

Next, we want to add our tabs. We will add three tabs (with a random text view as content) for this example and use a convenience method (setupTab) for clarity.

01 @Override
02 public voidonCreate(Bundle savedInstanceState) {
03     super.onCreate(savedInstanceState);
04     setContentView(R.layout.main);
05     mTabHost = (TabHost) findViewById(android.R.id.tabhost);
06     setupTab(newTextView(this),"Tab 1");
07     setupTab(newTextView(this),"Tab 2");
08     setupTab(newTextView(this),"Tab 3");
09 }
10 private voidsetupTab(final View view, final String tag) {
11     View tabview = createTabView(mTabHost.getContext(), tag);
12         TabSpec setContent = mTabHost.newTabSpec(tag).setIndicator(tabview).setContent(newTabContentFactory() {
13         publicView createTabContent(String tag) {returnview;}
14     });
15     mTabHost.addTab(setContent);
16 }
17  
18 private staticView createTabView(final Context context, final String text) {
19     View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg,null);
20     TextView tv = (TextView) view.findViewById(R.id.tabsText);
21     tv.setText(text);
22     returnview;
23 }

Normally, we would use setIndicator and give it either a string or a string and a drawable for icon. Now, we are creating a view (createTabViewmethod) and setting the indicator to that.

Step 3: Create custom tab's layout

In createTabView, we are inflating tabs_bg.xml. This layout is simple and just has a text view. If you wanted to customize this further, you could edit tabs_bg and add anImageView, etc.

tabs_bg.xml

01 <?xmlversion="1.0"encoding="utf-8"?>
02 <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03     android:id="@+id/tabsLayout"android:layout_width="fill_parent"
04     android:layout_height="fill_parent"
05     android:padding="10dip"android:gravity="center"android:orientation="vertical">
06  
07     <TextViewandroid:id="@+id/tabsText"android:layout_width="wrap_content"
08         android:layout_height="wrap_content"android:text="Title"
09         android:textSize="15dip"/>
10 </LinearLayout>

Step 4: Customize the look and feel of the view

At this point, we can run this example, but the tabs will be very boring and not really too customized. So from here, we need to figure out what we want to do to customize. For this tutorial, we will create a state list drawable for the background of the tabs using some color gradients. Other options is to use an actual drawable image or 9 patch png.

Let's edit our tabs_bg layout and add two attributes: a background that is pointed to a state list drawable, and atextColor that is pointed to a different state list drawable.

tabs_bg.xml

01 <?xmlversion="1.0"encoding="utf-8"?>
02 <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03     android:id="@+id/tabsLayout"android:layout_width="fill_parent"
04     android:layout_height="fill_parent"android:background="@drawable/tab_bg_selector"
05     android:padding="10dip"android:gravity="center"android:orientation="vertical">
06  
07     <TextViewandroid:id="@+id/tabsText"android:layout_width="wrap_content"
08         android:layout_height="wrap_content"android:text="Title"
09         android:textSize="15dip"android:textColor="@drawable/tab_text_selector"/>
10 </LinearLayout>

We can have the text change whether a tab is active, pressed, selected, or inactive. So let's create a state list for the text color.

tab_text_selector.xml

1 <?xmlversion="1.0"encoding="utf-8"?>
2 <selectorxmlns:android="http://schemas.android.com/apk/res/android">
3     <itemandroid:state_selected="true"android:color="@android:color/white"/>
4     <itemandroid:state_focused="true"android:color="@android:color/white"/>
5     <itemandroid:state_pressed="true"android:color="@android:color/white"/>
6     <itemandroid:color="#f8f8f8"/>
7 </selector>

And, we want the background color to change as well. Here's the selector XML for the tab background.

tab_bg_selector.xml

01 <?xmlversion="1.0"encoding="utf-8"?>
02 <selectorxmlns:android="http://schemas.android.com/apk/res/android">
03     <!--  Active tab -->
04     <itemandroid:state_selected="true"android:state_focused="false"
05         android:state_pressed="false"android:drawable="@drawable/tab_bg_selected"/>
06     <!--  Inactive tab -->
07     <itemandroid:state_selected="false"android:state_focused="false"
08         android:state_pressed="false"android:drawable="@drawable/tab_bg_unselected"/>
09     <!--  Pressed tab -->
10     <itemandroid:state_pressed="true"android:drawable="@android:color/transparent"/>
11     <!--  Selected tab (using d-pad) -->
12     <itemandroid:state_focused="true"android:state_selected="true"
13         android:state_pressed="false"android:drawable="@android:color/transparent"/>
14 </selector>

Now, with this selector notice we are setting the active and inactive tab backgrounds to another drawable. In this case, its a color gradient shape. You may want to use an image here.

Let's define tab_bg_selected.xml:

1 <?xmlversion="1.0"encoding="utf-8"?>
2 <shapexmlns:android="http://schemas.android.com/apk/res/android"
3     android:shape="rectangle">
4     <gradientandroid:startColor="#A8A8A8"android:centerColor="#7F7F7F"
5         android:endColor="#696969"android:angle="-90"/>
6 </shape>

Let's define tab_bg_unselected.xml:

1 <?xmlversion="1.0"encoding="utf-8"?>
2 <shapexmlns:android="http://schemas.android.com/apk/res/android"
3     android:shape="rectangle">
4     <gradientandroid:startColor="#5C5C5C"android:centerColor="#424242"
5         android:endColor="#222222"android:angle="-90"/>
6 </shape>

Now it's looking better.

Step 5: Final customizations

So now we have a workable custom tab solution. However, you may want to add a drawable to go between the tabs (a tab separator). While Android used to provide a tab separator attribute forTabWidget, it doesn't seem to exist anymore. So the solution is to add this drawable programmatically.

1 mTabHost.getTabWidget().setDividerDrawable(R.drawable.tab_divider);

Make sure to add this line before the calls to setupTab!

Here's our final product:

Another example using images instead of color gradients:

Android 定制 Tabs_第1张图片

Step 6: Download source

Feel free to download and browse the source code for this example here: http://code.google.com/p/android-custom-tabs/


你可能感兴趣的:(Android 定制 Tabs)