AndroidGUI24:TabHost常用技巧

掌握Android界面设计:TabHost多标签页布局实操 本文还有配套的精品资源,点击获取 简介:在Android开发中,界面设计对于用户体验至关重要。本主题以网易客户端为案例,详细讲解了如何使用TabHost组件实现多标签页界面设计,这是Android早期版本中常用的一种布局管理方式。文章首先介绍了TabHost的基本概念和如何在XML布局文件中配置它。随后深入探讨了TabWidget、FrameLayout、TabSpec等关... 阅读详情

在很多其他语言进行界面编程的时候,都有 Tab 这样的控件,在 Android 编程环境下也不例外。 TabHost 由一个 TabSpecs 和一个嵌套的 TabHost 组成,该嵌套的 TabHost 包含 tab 的标题以及 tab 的内容。一个 tab 的内容,可以是一个预先定义好的 View ,或者是通过 Intent 对象启动的 Activity ,或者是利用 TabContentFactory 所创建出来的 View 。

 

Tab 并没有看起来那么复杂。每个 tab 实际上就是一个 View 的容器。

 

有两种方式可以实现 tab 。一种是直接使用 TabActivity ,一种是不使用 TabActivity 。我们首先来看看使用 TabActivity 实现 tab 的情况。

 

第一种情况:使用 TabActivity

1.     创建一个 Android Project 。

2.     新建一个 xml 文件: tab_demo.xml ,使其内容如下:

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

< FrameLayout xmlns:android = "http://schemas.android.com/apk/res/android"

    android:orientation = "vertical"

    android:layout_width = "fill_parent"

    android:layout_height = "fill_parent"

    >

    < TextView android:id = "@+id/tab_demo_tv1"

        android:layout_width = "fill_parent"  

        android:layout_height = "fill_parent"  

        android:text = "tab_demo_tv1"

    />

    < LinearLayout android:id = "@+id/tab_linearlayout2"

        android:layout_width = "fill_parent"  

        android:layout_height = "fill_parent"

        android:orientation = "vertical"

    >

       < TextView android:id = "@+id/tab_demo_tv2"

        android:layout_width = "wrap_content"  

        android:layout_height = "wrap_content"  

        android:text = "tab_demo_tv2"

       />

      

       < Button

        android:layout_width = "fill_parent"  

        android:layout_height = "wrap_content"  

        android:text = "Tab demo Button"

       />

    </ LinearLayout >

   

    < TextView android:id = "@+id/tab_demo_tv3"

        android:layout_width = "fill_parent"  

        android:layout_height = "fill_parent"  

        android:text = "tab_demo_tv3"

    />

</ FrameLayout >

上面的第一和第三个 TextView ,也可以是 LinearLayout(tab_linearlayout2) 。

 

3.     修改 Activity 所对应的代码,使之如下:

package com.pat.gui;

 

import android.app.TabActivity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.widget.TabHost;

 

public class AndroidGUI24Activity extends TabActivity

{

    private TabHost tabhost ;

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super .onCreate(savedInstanceState);

        // 获取该 Activity 用于容纳 tab 的 TabHost 对象

        // Returns the TabHost the activity is using to host its tabs.

        tabhost = getTabHost();

       

        // 获取 LayoutInflater 对象

        LayoutInflater inflater = LayoutInflater.from ( this );

       

        // TabHost.getTabContentView 方法的作用: Get the FrameLayout which holds tab content

        // LayoutInflater.inflate 方法的作用:

        // Inflate a new view hierarchy from the specified xml resource.

        // 其原型为: public View inflate (int resource, ViewGroup root)

        // 参数:

        // resource   ID for an XML layout resource to load (e.g., R.layout.main_page)

        // root            Optional view to be the parent of the generated hierarchy.

        // 返回值:

        // The root View of the inflated hierarchy. If root was supplied, this is the root

        // View; otherwise it is the root of the inflated XML file.

        inflater.inflate(R.layout. tab_demo , tabhost .getTabContentView());

        // 上面这句话,就是将 tab_demo.xml 的内容,嵌入到 tabhost.getTabContentView() 所返回的 FrameLayout 中

       

        // 给 tabhost 增加 tab

        // newTabSpec(String tag) 返回一个 TabHost.TabSpec 对象,其参数用于标识一个 tab 的 tag ,为 String 类型

        // setIndicator(" 国籍 "): 显示 tab 上的文字

        // setContent(R.id.tab_demo_tv1) :指定 tab 的内容,必须为 id ,比如空间的 id 或者 layout 的 id

        tabhost .addTab( tabhost .newTabSpec( "tab1" ).setIndicator( " 国籍 " ).setContent(R.id. tab_demo_tv1 ));

        tabhost .addTab( tabhost .newTabSpec( "tab2" ).setIndicator( " 爱好 " ).setContent(R.id. tab_linearlayout2 ));

        tabhost .addTab( tabhost .newTabSpec( "tab3" ).setIndicator( " 职业 " ).setContent(R.id. tab_demo_tv3 ));

    

        // 指定显示第几个 tab

        tabhost .setCurrentTab(1);

       

        // 在上面的工作都做完之后,再调用 setContentView

        //setContentView(R.layout.main);

        setContentView( tabhost );

    }

}

 

运行结果:


可以看到是第 2 个 tab 出现在屏幕上。点击“国籍”和“职业”两个 tab 会看到与之分别对应的界面。

 

4.     在前面的代码中,我们将 3 个 tab 需要显示的内容均在 tab_demo.xml 这一个文件中规定了。事实上,我们还可以有另外一种做法,那就是让不同的 tab 分别对应不同的 xml 布局文件,为此,新建三个布局文件,并使之如下:

tab1.xml:

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

< LinearLayout

  xmlns:android = "http://schemas.android.com/apk/res/android"

  android:layout_width = "wrap_content"

  android:layout_height = "wrap_content"

  android:id = "@+id/tab1"

  android:orientation = "vertical" >

 

         < TextView

                  android:id = "@+id/tab1tv1"

                  android:layout_width = "wrap_content"

                  android:layout_height = "wrap_content"

                  android:text = "Tab1"

         />

        

         < Button

                  android:id = "@+id/tab1btn1"

                  android:layout_width = "wrap_content"

                  android:layout_height = "wrap_content"

                  android:text = " 按钮 1"

         />

</ LinearLayout >

 

tab2.xml:

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

< LinearLayout

       xmlns:android = "http://schemas.android.com/apk/res/android"

       android:layout_width = "wrap_content"

       android:layout_height = "wrap_content"

       android:id = "@+id/tab2"

       android:orientation = "vertical" >

 

 

       < TextView

                 android:layout_width = "wrap_content"

                 android:layout_height = "wrap_content"

                 android:text = "Tab2"

       />

      

       < Button

                 android:id = "@+id/tab2btn1"

                 android:layout_width = "wrap_content"

                android:layout_height = "wrap_content"

                 android:text = " 按钮 1"

       />

      

       < Button

                 android:id = "@+id/tab2btn2"

                 android:layout_width = "wrap_content"

                 android:layout_height = "wrap_content"

                 android:text = " 按钮 2"

       />    

</ LinearLayout >

 

tab3.xml:

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

< LinearLayout

       xmlns:android = "http://schemas.android.com/apk/res/android"

       android:layout_width = "wrap_content"

       android:layout_height = "wrap_content"

       android:id = "@+id/tab3"

         android:orientation = "vertical" >

 

 

       < TextView

                 android:layout_width = "wrap_content"

                 android:layout_height = "wrap_content"

                 android:text = "Tab3"

       />  

      

       < Button

                 android:id = "@+id/tab3btn1"

                 android:layout_width = "wrap_content"

                 android:layout_height = "wrap_content"

                 android:text = " 按钮 1"

       />

      

       < Button

                 android:id = "@+id/tab3btn2"

                 android:layout_width = "wrap_content"

                 android:layout_height = "wrap_content"

                 android:text = " 按钮 2"

       />

      

       < Button

                 android:id = "@+id/tab3btn3"

                 android:layout_width = "wrap_content"

                android:layout_height = "wrap_content"

                 android:text = " 按钮 3"

       />             

</ LinearLayout >

 

5.     对应地修改 Activity 的代码,使之如下:

package com.pat.gui;

 

import android.app.TabActivity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TabHost;

 

public class AndroidGUI24Activity extends TabActivity

implements

OnClickListener

{

         private TabHost tabhost ;

         private Button tab1btn1 ;

         private Button tab2btn1 ;

         private Button tab2btn2 ;

         private Button tab3btn1 ;

         private Button tab3btn2 ;

         private Button tab3btn3 ;

       @Override

       public void onCreate(Bundle savedInstanceState)

       {

        super .onCreate(savedInstanceState);

        // 获取该 Activity 用于容纳 tab 的 TabHost 对象

        // Returns the TabHost the activity is using to host its tabs.

        tabhost = getTabHost();

       

        // 获取 LayoutInflater 对象

        LayoutInflater inflater = LayoutInflater.from ( this );

       

        // TabHost.getTabContentView 方法的作用: Get the FrameLayout which holds tab content

        // LayoutInflater.inflate 方法的作用:

        // Inflate a new view hierarchy from the specified xml resource.

        // 其原型为: public View inflate (int resource, ViewGroup root)

         // 参数:

        // resource   ID for an XML layout resource to load (e.g., R.layout.main_page)

        // root            Optional view to be the parent of the generated hierarchy.

        // 返回值:

        // The root View of the inflated hierarchy. If root was supplied, this is the root

        // View; otherwise it is the root of the inflated XML file.

       

        // 下面这几句话,就是将 tab1.xml 、 tab2.xml 、 tab3.xml 的内容,全嵌入到 tabhost.getTabContentView()

        // 所返回的 FrameLayout 中。

        inflater.inflate(R.layout. tab1 , tabhost .getTabContentView());

        inflater.inflate(R.layout. tab2 , tabhost .getTabContentView());

        inflater.inflate(R.layout. tab3 , tabhost .getTabContentView());

       

        // 给 tabhost 增加 tab

        // newTabSpec(String tag) 返回一个 TabHost.TabSpec 对象, TabHost.TabSpec

        // setIndicator(" 国籍 "): 显示 tab 上的文字

        // setContent(R.id.tab_demo_tv1) :指定 tab 的内容

        tabhost .addTab( tabhost .newTabSpec( "tab1" ).setIndicator( " 国籍 " ).setContent(R.id. tab1 ));

        tabhost .addTab( tabhost .newTabSpec( "tab2" ).setIndicator( " 爱好 " ).setContent(R.id. tab2 ));

        tabhost .addTab( tabhost .newTabSpec( "tab3" ).setIndicator( " 系统 " ).setContent(R.id. tab3 ));

       

        // 指定显示第几个 tab

        tabhost .setCurrentTab(1);

       

        // 在上面的工作都做完后,调用 setContentView

        //setContentView(R.layout.main);

        setContentView( tabhost );

      

        // 获取 6 个按钮对象,并分别给它们增加 OnClickListener

        tab1btn1 = (Button)findViewById(R.id. tab1btn1 );

        tab1btn1 .setOnClickListener( this );

       

        tab2btn1 = (Button)findViewById(R.id. tab2btn1 );

        tab2btn2 = (Button)findViewById(R.id. tab2btn2 );

        tab2btn1 .setOnClickListener( this );

        tab2btn2 .setOnClickListener( this );

       

        tab3btn1 = (Button)findViewById(R.id. tab3btn1 );

        tab3btn2 = (Button)findViewById(R.id. tab3btn2 );

        tab3btn3 = (Button)findViewById(R.id. tab3btn3 );

        tab3btn1 .setOnClickListener( this );

        tab3btn2 .setOnClickListener( this );

        tab3btn3 .setOnClickListener( this );

       }

 

         //@Override

         public void onClick(View v)

         {

                    switch (v.getId())

                    {

                    case R.id. tab1btn1 :

                            tabhost .setCurrentTab(1);          // 跳转到第二个 tab

                            break ;

                  case R.id. tab2btn1 :

                             tabhost .setCurrentTab(0);          // 跳转到第一个 tab

                             break ;

                   case R.id. tab2btn2 :

                            tabhost .setCurrentTab(2);          // 跳转到第三个 tab

                             break ;

                   case R.id. tab3btn1 :

                            tabhost .setCurrentTab(0);          // 跳转到第一个 tab

                             break ;      

                   case R.id. tab3btn2 :

                            tabhost .setCurrentTab(1);          // 跳转到第二个 tab

                             break ;

                   case R.id. tab3btn3 :

                            tabhost .setCurrentTab(2);          // 跳转到第三个 tab( 自己 )

                             break ;

                    }

         }

}

         运行结果如下:

        

         可以发现,点击“按钮 1 ”会跳转到“国籍”,点击“按钮 2 ”会跳转到“系统”

 

6.     在上面的基础上,我们给每个 tab 增加一个图标。为此我们将 amplifer_1.png 、 basketball.png 和 cn.png 等 3 个图片文件拷贝到 res/drawable-mdpi 文件夹下,然后修改 Activity 的代码使之如下 ( 注意下面的粗体字部分未改动部分 ) :

package com.pat.gui;

 

import android.app.TabActivity;

import android.content.res.Resources;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TabHost;

 

public class AndroidGUI24Activity extends TabActivity

implements

OnClickListener

{

private TabHost tabhost ;

private Resources res ;

private Button tab1btn1 ;

private Button tab2btn1 ;

private Button tab2btn2 ;

private Button tab3btn1 ;

private Button tab3btn2 ;

private Button tab3btn3 ;

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super .onCreate(savedInstanceState);

        // 获取该 Activity 用于容纳 tab 的 TabHost 对象

        // Returns the TabHost the activity is using to host its tabs.

        tabhost = getTabHost();

       

        res = getResources();

       

        // 获取 LayoutInflater 对象

        LayoutInflater inflater = LayoutInflater.from ( this );

       

        // TabHost.getTabContentView 方法的作用: Get the FrameLayout which holds tab content

        // LayoutInflater.inflate 方法的作用:

        // Inflate a new view hierarchy from the specified xml resource.

        // 其原型为: public View inflate (int resource, ViewGroup root)

        // 参数:

        // resource   ID for an XML layout resource to load (e.g., R.layout.main_page)

        // root            Optional view to be the parent of the generated hierarchy.

        // 返回值:

        // The root View of the inflated hierarchy. If root was supplied, this is the root

        // View; otherwise it is the root of the inflated XML file.

       

        // 下面这几句话,就是将 tab1.xml 、 tab2.xml 、 tab3.xml 的内容,全嵌入到 tabhost.getTabContentView()

        // 所返回的 FrameLayout 中。

        inflater.inflate(R.layout. tab1 , tabhost .getTabContentView());

        inflater.inflate(R.layout. tab2 , tabhost .getTabContentView());

        inflater.inflate(R.layout. tab3 , tabhost .getTabContentView());

       

        // 给 tabhost 增加 tab

        // newTabSpec(String tag) 返回一个 TabHost.TabSpec 对象, TabHost.TabSpec

        // setIndicator(" 国籍 "): 显示 tab 上的文字

        // setContent(int id) :指定 tab 的内容

        tabhost .addTab( tabhost .newTabSpec( "tab1" ).setIndicator( " 国籍 " , res .getDrawable(R.drawable. cn ) )

.setContent(R.id. tab1 ));

        tabhost .addTab( tabhost .newTabSpec( "tab2" ).setIndicator( " 爱好 " , res .getDrawable(R.drawable. basketball ) )

.setContent(R.id. tab2 ));

        tabhost .addTab( tabhost .newTabSpec( "tab3" ).setIndicator( " 系统 " , res .getDrawable(R.drawable. amplifer_1 ) )

.setContent(R.id. tab3 ));

       

        // 指定显示第几个 tab

        tabhost .setCurrentTab(1);

       

        // 在上面的工作都做完后,调用 setContentView

        //setContentView(R.layout.main);

        setContentView( tabhost );

      

        // 获取 6 个按钮对象,并分别给它们增加 OnClickListener

        tab1btn1 = (Button)findViewById(R.id. tab1btn1 );

        tab1btn1 .setOnClickListener( this );

       

        tab2btn1 = (Button)findViewById(R.id. tab2btn1 );

        tab2btn2 = (Button)findViewById(R.id. tab2btn2 );

        tab2btn1 .setOnClickListener( this );

        tab2btn2 .setOnClickListener( this );

       

        tab3btn1 = (Button)findViewById(R.id. tab3btn1 );

         tab3btn2 = (Button)findViewById(R.id. tab3btn2 );

        tab3btn3 = (Button)findViewById(R.id. tab3btn3 );

        tab3btn1 .setOnClickListener( this );

        tab3btn2 .setOnClickListener( this );

        tab3btn3 .setOnClickListener( this );

    }

 

//@Override

public void onClick(View v)

{

           switch (v.getId())

           {

           case R.id. tab1btn1 :

                    tabhost .setCurrentTab(1);          // 跳转到第二个 tab

                    break ;

           case R.id. tab2btn1 :

                    tabhost .setCurrentTab(0);          // 跳转到第一个 tab

                    break ;

           case R.id. tab2btn2 :

                    tabhost .setCurrentTab(2);          // 跳转到第三个 tab

                    break ;

           case R.id. tab3btn1 :

                    tabhost .setCurrentTab(0);          // 跳转到第一个 tab

                    break ;      

           case R.id. tab3btn2 :

                    tabhost .setCurrentTab(1);          // 跳转到第二个 tab

                    break ;

           case R.id. tab3btn3 :

                    tabhost .setCurrentTab(2);          // 跳转到第三个 tab( 自己 )

                    break ;

           }

}

}

运行结果为:


其它和 5 中的运行结果相同。

 

7.     在本文开始出,曾经提到“或者是通过 Intent 对象启动的 Activity ”,也就是说 setContent 的参数可以是一个 Intent 对象,然后用该对象启动另外一个 Activity 。为此我们先创建一个 Activity 类,并为它指定相应的 layout 。假定我们让第三个 tab 显示的内容为 Intent 对象所指定的 Activity 。 Layout 内容如下:

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

< LinearLayout

  xmlns:android = "http://schemas.android.com/apk/res/android"

  android:layout_width = "wrap_content"

  android:layout_height = "wrap_content" >

 

< TextView

           android:layout_width = "wrap_content"

                  android:layout_height = "wrap_content"

                  android:text = "Hello, Android"

                  android:textSize = "30px"

                  android:textColor = "#FF0" />       

</ LinearLayout >

对应的 Activity 代码如下:

package com.pat.gui;

 

import android.app.Activity;

import android.os.Bundle;

 

public class ThirdTab extends Activity

{

                  @Override

                  protected void onCreate(Bundle savedInstanceState)

                  {

                            super.onCreate(savedInstanceState);

                            setContentView(R.layout.thirdtab);

                  }

}

在 AndroidManifest.xml 中的 Application 标签内,增加对 ThirdTab 的描述:

<activity android:name=".ThirdTab" />

 

8.     现在,咱们来修改 AndroidGUI24Activity 的代码,使之如下 ( 注意粗体字部分的代码变化 ) :

package com.pat.gui;

 

import android.app.TabActivity;

import android.content.Intent;

import android.content.res.Resources;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TabHost;

 

public class AndroidGUI24Activity extends TabActivity

implements

OnClickListener

{

         private TabHost tabhost;

         private Resources res;

        

         private Button tab1btn1;

        

         private Button tab2btn1;

         private Button tab2btn2;

        

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super .onCreate(savedInstanceState);

        // 获取该 Activity 用于容纳 tab 的 TabHost 对象

        // Returns the TabHost the activity is using to host its tabs.

         tabhost = getTabHost();

       

        res = getResources();

       

        // 获取 LayoutInflater 对象

        LayoutInflater inflater = LayoutInflater.from (this );

       

        // TabHost.getTabContentView 方法的作用: Get the FrameLayout which holds tab content

        // LayoutInflater.inflate 方法的作用:

        // Inflate a new view hierarchy from the specified xml resource.

        // 其原型为: public View inflate (int resource, ViewGroup root)

        // 参数:

        // resource           ID for an XML layout resource to load (e.g., R.layout.main_page)

        // root                    Optional view to be the parent of the generated hierarchy.

        // 返回值:

        // The root View of the inflated hierarchy. If root was supplied, this is the root

        // View; otherwise it is the root of the inflated XML file.

       

        // 下面这几句话,就是将 tab1.xml 、 tab2.xml 的内容,全嵌入到 tabhost.getTabContentView()

        // 所返回的 FrameLayout 中。这次我们仅 inflate 两个 tab 的内容,第三个 tab 将有一个 Intent 对象指定

        inflater.inflate(R.layout.tab1 , tabhost.getTabContentView());

        inflater.inflate(R.layout.tab2 , tabhost.getTabContentView());

       

        // 给 tabhost 增加 tab

        // newTabSpec(String tag) 返回一个 TabHost.TabSpec 对象, TabHost.TabSpec

        // setIndicator(" 国籍 "): 显示 tab 上的文字

        // setContent(int id) :指定 tab 的内容

        tabhost.addTab(tabhost.newTabSpec("tab1").setIndicator(" 国籍 ", res.getDrawable(R.drawable.cn )).setContent(R.id.tab1 ));

        tabhost.addTab(tabhost.newTabSpec("tab2").setIndicator(" 爱好 ", res.getDrawable(R.drawable.basketball )).setContent(R.id.tab2 ));

         tabhost.addTab(tabhost.newTabSpec("tab3").setIndicator(" 系统 ",res.getDrawable(R.drawable.amplifer_1 ))

.setContent(new Intent(this , ThirdTab.class ) ));

        // 指定显示第几个 tab

        tabhost.setCurrentTab(1);

       

        // 在上面的工作都做完后,调用 setContentView

         //setContentView(R.layout.main);

        setContentView(tabhost);

      

        // 获取 6 个按钮对象,并分别给它们增加 OnClickListener

        tab1btn1 = (Button)findViewById(R.id.tab1btn1 );

        tab1btn1.setOnClickListener(this );

       

        tab2btn1 = (Button)findViewById(R.id.tab2btn1 );

        tab2btn2 = (Button)findViewById(R.id.tab2btn2 );

        tab2btn1.setOnClickListener(this );

        tab2btn2.setOnClickListener(this );

    }

 

         //@Override

         public void onClick(View v)

         {

                   switch (v.getId())

                   {

                   case R.id.tab1btn1 :

                            tabhost.setCurrentTab(1); // 跳转到第二个 tab

                            break ;

                   case R.id.tab2btn1 :

                            tabhost.setCurrentTab(0); // 跳转到第一个 tab

                            break ;

                   case R.id.tab2btn2 :

                            tabhost.setCurrentTab(2); // 跳转到第三个 tab

                            break ;

                   }

         }

}

运行结果如下 ( 点击“系统”这个 tab) :


点击“国籍”、“爱好”和“系统”,各 tab 之间可以进行很好的切换。

 

第二种情况:不使用 TabActivity

不使用 TabActivity 来 实现Tab 功能 ,情况要稍微复杂一些,但同时也更灵活一些,比如可以把 tab 的位置放在屏幕的下方。为此,需要对 TabHost 、 TabWidget 底层有所了解。在定义包含各 tab 信息的 xml 文件中,必须:

a.     根布局必须是 TabHost

b.     在 TabHost 内,必须包含一个垂直的 LinearLayout

c.     在 LinearLayout 中,必须包含一个 TabWidget 和一个 FrameLayout ,且其中 TabWidget 的 id 必须命名为 @android:id/tabs , FrameLayout 的 id 必须命名为 @android:id/tabcontent ,各 tab 的内容可以定义在 FrameLayout 中。

 

1.     创建一个新的布局文件: tab_demo2.xml ,并使之如下:

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

< TabHost

         xmlns:android = "http://schemas.android.com/apk/res/android"

         android:layout_width = "fill_parent"

         android:layout_height = "fill_parent"

         android:id = "@+id/v_tabhost"

>  

        

         < LinearLayout

                  android:orientation = "vertical"

                  android:layout_width = "fill_parent"  

                android:layout_height = "fill_parent"

         >

                  < FrameLayout

                             android:id = "@android:id/tabcontent "

                           android:layout_width = "fill_parent"  

                 android:layout_height = "fill_parent"

                 android:layout_weight = "1"

                  >

                           < LinearLayout

                                     android:id = "@+id/tab1"

                                     android:orientation = "vertical"

                                     android:layout_width = "fill_parent"  

                                   android:layout_height = "fill_parent"

                           >

                                     < TextView

                                              android:layout_width = "wrap_content"  

                                            android:layout_height = "wrap_content"

                                            android:text = "Hello, Android1"

                                 android:textColor = "#FF0"

                                            android:textSize = "30px"

                                     >

                                     </ TextView >

                                     < Spinner

                                                android:id = "@+id/Spinner01"

                                                android:layout_width = "160px"

                                                android:layout_height = "wrap_content"

                                                android:entries = "@array/cities"

                                                android:prompt = "@string/spin_prompt"

                                       />      

                           </ LinearLayout >

                          

                           < LinearLayout

                                     android:id = "@+id/tab2"

                                     android:orientation = "vertical"

                                     android:layout_width = "fill_parent"  

                                   android:layout_height = "fill_parent"

                           >

                                     < TextView

                                              android:layout_width = "wrap_content"  

                                             android:layout_height = "wrap_content"

                                            android:text = "Hello, Android2"

                                            android:textColor = "#F0F"

                                            android:textSize = "30px"

                                    >

                                     </ TextView >

                                    

                                     < DigitalClock

                                                android:id = "@+id/digital_clock"

                                                android:layout_width = "wrap_content"

                                                android:layout_height = "wrap_content"

                                                android:textSize = "50px"

                                       />               

                           </ LinearLayout >                        

                          

                           < LinearLayout

                                     android:id = "@+id/tab3"

                                     android:orientation = "vertical"

                                     android:layout_width = "fill_parent"  

                                   android:layout_height = "fill_parent"

                           >

                                     < TextView

                                              android:layout_width = "wrap_content"  

                                            android:layout_height = "wrap_content"

                                            android:text = "Hello, Android3"

                                            android:textColor = "#0FF"

                                            android:textSize = "30px"

                                     >

                                     </ TextView >

                                     < AnalogClock

                                                android:id = "@+id/analog_clock"

                                                android:layout_width = "wrap_content"

                                                android:layout_height = "wrap_content"

                                       />

                           </ LinearLayout >                        

                  </ FrameLayout >

                    

        < TabWidget  

            android:id = "@android:id/tabs "

            android:layout_width = "fill_parent"  

            android:layout_height = "60px" />

         </ LinearLayout >

</ TabHost >

         注意上面代码中,粗体字部分的写法。

其中 android:layout_weight="1" 必须要出现在 FrameLayout 的属性中,否则 tab 不可见。

 

2.    在strings.xml中增加如下内容:

  < string name = "spin_prompt" > 请选择城市 </ string >

< string-array name = "cities" >

         < item > 北京 </ item >

         < item > 上海 </ item >

         < item > 南京 </ item >

         < item > 乌鲁木齐 </ item >

         < item > 哈尔滨 </ item >

         < item > 符拉迪沃斯托克 </ item >

</ string-array >


3.     修改 AndroidGUI24Activity 的代码如下:

package com.pat.gui;

import android.app.Activity;

import android.content.res.Resources;

import android.os.Bundle;

import android.widget.TabHost;

 

public class AndroidGUI24Activity extends Activity

{        

   private Resources res ;

    //@Override

    public void onCreate(Bundle savedInstanceState)

    {

        super .onCreate(savedInstanceState);

        setContentView(R.layout. tab_demo2 );

              // 下面两行对于不使用 TabActivity 实现 tab 效果是必须的

        TabHost tabhost = (TabHost)findViewById(R.id. v_tabhost );

        tabhost.setup();

       

        res = getResources();

       

        tabhost.addTab(tabhost.newTabSpec( "tab1" ).setIndicator( " 国籍 " , res .getDrawable(R.drawable. cn ))

                     .setContent(R.id. tab1 ));

         tabhost.addTab(tabhost.newTabSpec( "tab2" ).setIndicator( " 爱好 " , res .getDrawable(R.drawable. basketball ))

                     .setContent(R.id. tab2 ));

        tabhost.addTab(tabhost.newTabSpec( "tab3" ).setIndicator( " 系统 " , res .getDrawable(R.drawable. amplifer_1 ))

                     .setContent(R.id. tab3 ));

    }

}

运行结果:

 

LayoutInflater.from(context).inflate()方法的调研 立即下载

相关推荐

群晖NAS变身私有Git服务器:DS218+部署与TortoiseGit客户端实战指南

本文详细介绍了如何将群晖NAS(如DS218+)变身为私有Git服务器,并配置TortoiseGit客户端实现高效代码管理。通过硬件检查、系统更新、Git Server套件安装及权限配置等步骤,帮助开发者在局域网内搭建安全、高速的代码托管环境,特别适合小团队协作。

weixin_29252171的博客 224

Android选项卡TabHost功能和用法

1、选项卡TabHost介绍 TabHost可以方便地在窗口上放置多个标签页,每个标签页相当于获得了一个与外部容器大小相同的组件摆放区域 TabHost是一个简单的容器,提供如下两种方法来创建选项卡 newTabSpec(String tag):创建选项卡 addTab(TabHost.TabSpec tabSpec):添加选项卡 使用TabHost有三种方法 2、方法1,继承TabActivi...

钻石 4万+

ArcGIS基础:CAD数据转换为GIS数据(符号化显示、数据转换、线转面、空间连接)

1、符号化显示: CAD数据加载进来有很多列表,包含了点【point】、线【polyline】、面【polygon】、标注数据【Annotation】等数据,本次实验我们需要用到的是面数据,也就是.dwgPolygong格式的数据。如下图所示: 把数据加载进来,然后在2处打开属性表,查看CAD数据的属性表,打开后可以发现【layer】图层表示就是地块的用地性质,它就是符号化显示的依据。 我们在数据上右键【属性】,打开图层属性,找到【符号系统】,选择类别中的【唯一值】,然后在【值字段】下拉选择【layer】,

yuanYW7556的博客 2万+

android之tab分页标签的实现方法,Android开发之TabHost组件实例

大家在进行其他语言的编程时应该都见过甚至用过标签组件,Android开发中也经常会用到标签组件。一般情况下如果一屏放不下所有组件,则我们可能会选择滚动视图,另外一种方法就是使用标签组件对屏幕进行分页,单击不同标签显示它对应的内容。Android中的TabHost是标签组件的核心类,也是标签的集合,每一个标签显示一个View或一个Activity。TabHost简介所谓的TabHost是提供选项卡(...

weixin_34586802的博客 480

Windows10下MATLAB2017a安装与破解实战:手把手教你搞定双镜像加载

本文详细介绍了在Windows 10系统下安装和破解MATLAB 2017a的完整步骤,包括双镜像加载、许可证配置及常见问题解决方案。通过手把手教程,帮助用户顺利完成安装并优化性能,特别适合工程计算领域的初学者和专业人士。

weixin_29053383的博客 419

PCI-Express、MiniPCIe、ExpressCard接口转换说明/引脚互换关系

通过引脚PIN互换可以在PCI-Express、MiniPCIe、ExpressCard之间切换不同的接口;提供接口引脚表和标准尺寸图。

tech34的博客 7125

关于带Tab的Android应用

1. 使用TabActivity,Tab在上方 (TabHost中包含了一个TabWidget--a list of tabs) 取得TabHost----》将layout Inflate到myTabhost.getTabContentView()中----》myTabhost.addTab添加每一个Tab,并指定每一个Tab对应的显示区域(使用TabSpec的setContent方法)。

lihuapinghust的专栏 622

Applied Energy期刊小白论文投稿模板-流程经验分享

Applied Energy期刊小白论文投稿模板-流程经验分享,Elsevier期刊(爱思唯尔)投稿流程

zzu_Flyer的博客 4万+

Android之UI学习篇九:使用TabHost实现卡片选项菜单

TabHost是一个装载选项卡窗口的容器,实现分模块显示的效果。像新浪微博客户端、微信客户端都是使用tabehost组件来开发的。 TabHost的组成: |---TabWidget:实现标签栏,可供用户选择的标签集合; |---FrameLayout:实现显示内容的帧布局. TabHost有两种实现方式: 一、在布局文件中定义TabHost 1、在配置文件中使用TabH...

移动开发记录 258

RAP 语义键:让 UUID 世界变得可读、可导航、可校验

RAP 语义键的核心价值与实现要点 语义键(Semantic Key)是 ABAP RAP 模型中连接技术实现与业务体验的关键设计:通过为实体指定一组业务可读的标识字段(如订单号、物料编码等),在保持技术主键(如UUID)不变的同时,显著提升用户界面的可读性和导航体验。 主要优势: 提升UI可读性:Fiori元素会突出显示语义键字段,帮助用户快速识别关键业务数据 改善导航体验:OData URL会使用可读的语义键而非技术ID,便于分享和排查问题 降低沟通成本:业务人员能准确引用有意义的业务标识而非技术ID

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 156

最新扣子智能体教程:手把手教你接入抖音评论区,实现自动回复

摘要:本文介绍如何利用扣子(Coze)平台搭建智能体实现抖音评论自动回复。从准备工作(账号注册、权限申请)到智能体创建(提示词优化、模型选择),再到抖音API接入和自动回复逻辑设置,详细说明了每个步骤的操作方法。文章还提供了回复模板示例和优化建议,帮助提升互动效率。通过这套方案,创作者可以显著减轻评论区管理压力,增强用户互动体验。(149字)

互联网架构师笔记 988

TabHost的两种实现方式

TabHost的两种使用方式

XYJ的博客 1269

从 30 天试用到企业级落地,2026 年学习和试用 SAP AI 的完整路线图

摘要:SAP AI产品体系存在试用版本与商业版本的边界模糊问题,需区分业务嵌入AI(如Joule)、开发者工具(SAP Build Code)和AI基础平台(Generative AI Hub)三个层级。建议学习路径:1)通过SAP Learning专区掌握理论框架;2)优先使用30天Generative AI Hub基础试用体验模型编排;3)结合90天BTP试用账户开发完整应用。特别注意免费计划已陆续停止,需以最新官方文档为准。开发者应重点关注AI如何与SAP技术栈(CAP、Fiori等)集成,而非单纯功

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 116

无法显示TabHost的setIndicator设置的图片的问题解决办法

本想做一个 带有图片的 分页显示的demo 但是 自己的代码写的也木有问题 ,所以只有mainifest 有问题了 主要是用到了 Tabhost <TabHost xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t...

Hufan的专栏 404

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android tabhost的使用方法,Android TabHost组件使用方法详解

最近研究了一下contacts源码,仿照上面自己写了一个tabhosttest程序,现整理如下:main.xml布局文件:android:id="@android:id/tabhost"android:layout_width="match_parent"android:layout_height="match_parent">android:orientation="vertical"an...

weixin_32821477的博客 402

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

android tabhost的使用方法,android TabHost(选项卡)的使用方法

首先,定义TabHost的布局文件:复制代码 代码如下:android:id="@android:id/tabhost" android:layout_width="fill_parent"android:layout_height="fill_parent">android:layout_width="fill_parent" android:layout_height="fill_par...

weixin_32571965的博客 335

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

TabHost详解

前言:今天仔细研究了下TabHost,主要是为了实现微信底部导航栏的功能,最后也给出一个链接,这位老兄用TabHost基本做出来了微信导航栏。 正文 TabHost的实现分为两种,一个是不继承TabActivity,一个是继承自TabActivity;当然了选用继承自TabActivity的话就相对容易一些,下面来看看分别是怎样来实现的吧。 一、定义tabhost:不用继承TabActivi

启舰 8万+

getTabHost两种实现方式

第一种:继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost。只要定义具体Tab内容布局就行了. xml布局: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pare...

weixin_30502965的博客 285

【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)

今天讲一下,如何在TabHost中,再放TabHost。先来看一下效果。一层TabHost两层Tabhost (内部TabHots在上面)两层TabHost (内层TabHots在下面)下面说一下代码,一共3个 java类,3个xml布局文件。看一下主画面:main.xml

幻影浪子 1万+

Android成长之路-LayoutInflater和inflate的用法

在这里用Tabhost的例子来说明: package cn.csdn.activity; import android.app.TabActivity; import android.os.Bundle; import android.view.LayoutInflater; import android.widget.TabHost; public class TabHostActivit

2万+

Android:TabView使用总结

原帖地址:http://www.cnblogs.com/longlybits/archive/2011/12/01/2270830.html 之前在t.sina.com.cn/kevinlynx陆续贴了些android开发涉及到的一些code snippets,主要目的是记录,供以后需要的时候查阅方便。但是因为miniblog的字数限制,在记录较多信息的时候还是有诸多不便。so,

Android 3095

Inflate()---Android之Inflate()方法用途

Inflate()作用就是将xml定义的一个布局找出来,但仅仅是找出来而且隐藏的,没有找到的同时并显示功能。最近做的一个项目就是这一点让我迷茫了好几天。 android上还有一个与Inflate()类似功能的方法叫findViewById(),二者有时均可使用,但也有区别 区别在于: 如果你的Activity里用到别的layout,比如对话框layout,你还要设置这个layout上的其

yyb.ye专栏 8326
上一篇: AndroidGUI23:水平方向和垂直方向同时滚动
下一篇: 平分一个数,使得各份相乘所得到的积最大
pathuang68
博客等级 码龄18年 1821粉丝 194原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值