[译文]Tab Layout - Android SDK Tutorials系列

Tab Layout

要创建一个标签式UI,你需要使用 TabHostTabWidget 。TabHost必须是XML布局文件的根节点,它包含了一个 TabWidget 和一个 FrameLayout ,分别显示标签和标签内容。

 

有两种方式来实现标签内容:1. 在同一个Activity里面切换不同的View;2.使用标签在完全独立的Activity之间切换。可以根据你的需求决定选择哪种方式。但是如果每个标签提供的用户活动明显不同,那最好为每个标签提供一个独立的Activity,这样你能很方便的分组管理你的标签内容,而不是只用一个Activity从而乱成一锅粥。

这个教程里,采用第一种方式,每个标签使用一个独立的Activity。

  1. 创建一个工程:HelloTabWidget
  2. 然后,创建3个独立的Activity子类:ArtistsActivity, AlbumsActivity, 和SongsActivity. 每个Activity代表一个标签。现在,让每个Activity用TextView显示一句简单的话。示例:
    public class ArtistsActivity extends Activity {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            TextView textview = new TextView(this);
            textview.setText("This is the Artists tab");
            setContentView(textview);
        }
    }
    注意,这里简单起见,没有使用XML布局文件,只是创建了一个TextView,显示一句简单的话。一共创建3个类似的Activity,记得在Android Manifest文件里登记这3个Activity:
    <activity android:name=".ArtistsActivity" />
    <activity android:name=".AlbumsActivity" />
    <activity android:name=".SongsActivity" />

     

  3. 你需要为每个标签准备一个图标。每个图标有两个版本:一个在标签被选中的时候显示,一个在没有被选中的时候显示。通常的设计建议选中的时候显示深色(灰色),没选中的时候显示浅色(白色)。(请参考图标设计指南)。示例:

    ic_tab_artists_white ic_tab_artists_grey

    在本教程里,你可以把这两个图片用在所有的标签上。(但是在开发自己应用时候,必须自己设计图标。)

    现在创建一个state-list drawable,来设置每个标签状态显示哪个图片。

    1. 将图标文件保存到res/drawable/ 目录(补充:高版本里面会有drawable-ldpi,drawable-mdpi, drawable-hdpi,甚至还有drawable-xhdpi,具体怎么用后面的教程会有介绍)
    2. res/drawable/ 目录下创建一个新的XML文件ic_tab_artists.xml,内容如下:
      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <!-- When selected, use grey -->
          <item android:drawable="@drawable/ic_tab_artists_grey"
                android:state_selected="true" />
          <!-- When not selected, use white-->
          <item android:drawable="@drawable/ic_tab_artists_white" />
      </selector>
      这就是一个 state-list drawable, 用来显示标签图标。当标签状态改变的时候,标签图片会自动变换。为每个标签都创建这样一个XML文件,内容类似,只是用到的图标名字根据实际情况修改。
  4. 打开res/layout/main.xml修改如下:
    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp">
            <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:padding="5dp" />
        </LinearLayout>
    </TabHost>
    这个布局会显示标签,并能在不同Activity之间提供导航功能。

    TabHost里面需要包括一个TabWidget和一个FrameLayout。这里的LinearLayout将TabWidget和FrameLayout按垂直方向排列。FrameLayout里存放标签内容,现在还是空的,TabHost将自动将每个Activity嵌入它里面。

    TabWidget和FrameLayout两个元素的ID分别是tabstabcontent。这两个ID都必须要有,TabHost会通过这个两个ID来引用它们。

     

  5. 现在打开HelloTabWidget.java 并修改其基类为TabActivity:
    public class HelloTabWidget extends TabActivity {
  6. onCreate()修改为:
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        Resources res = getResources(); // Resource object to get Drawables
        TabHost tabHost = getTabHost();  // The activity TabHost
        TabHost.TabSpec spec;  // Resusable TabSpec for each tab
        Intent intent;  // Reusable Intent for each tab
    
        // Create an Intent to launch an Activity for the tab (to be reused)
        intent = new Intent().setClass(this, ArtistsActivity.class);
    
        // Initialize a TabSpec for each tab and add it to the TabHost
        spec = tabHost.newTabSpec("artists").setIndicator("Artists",
                          res.getDrawable(R.drawable.ic_tab_artists))
                      .setContent(intent);
        tabHost.addTab(spec);
    
        // Do the same for the other tabs
        intent = new Intent().setClass(this, AlbumsActivity.class);
        spec = tabHost.newTabSpec("albums").setIndicator("Albums",
                          res.getDrawable(R.drawable.ic_tab_albums))
                      .setContent(intent);
        tabHost.addTab(spec);
    
        intent = new Intent().setClass(this, SongsActivity.class);
        spec = tabHost.newTabSpec("songs").setIndicator("Songs",
                          res.getDrawable(R.drawable.ic_tab_songs))
                      .setContent(intent);
        tabHost.addTab(spec);
    
        tabHost.setCurrentTab(2);
    }
    以上内容创建各个标签,以及标签上的图标和文字,并给它分配一个Activity。

    首先调用getTabHost()方法获得对TabHost的引用。然后,为每个标签创建一个TabHost.TabSpec来设置标签属性。

    newTabSpec(String)方法创建一个新的 TabHost.TabSpec,用一个字符串型名字来加以区分。调用TabHost.TabSpecsetIndicator(CharSequence, Drawable)  方法来设置标签的文字和图标,再调用setContent(Intent) 设置一个Intent来打开对应的Activity。

    最后,调用setCurrentTab(int) 方法来设置默认显示哪个标签,参数是标签的位置索引(从0开始)。

    可以看到,TabWidget一次也没使用过,这是因为TabWidget必须总是TabHost的一个元素,你用它来处理几乎所有的标签交互操作。所以当一个标签被加入TabHost以后,它会被自动添加到TabWidget上。

  7. 现在打开Android Manifest 文件,添加主题NoTitleBar HelloTabWidget的 <activity> tag,这个主题不会在最上面显示默认的应用标题,给标签留出更大的空间,每个标签都有自己的标题。 <activity> 标识看起来应该像这样:
    <activity android:name=".HelloTabWidget" android:label="@string/app_name"
              android:theme="@android:style/Theme.NoTitleBar">
  8. 运行应用。

你的应用看起来应该像这样(不过你的图标可能不一样):

posted on 2011-12-08 12:21  OnionD  阅读(279)  评论(1编辑  收藏  举报

导航