Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35551
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 142
  • 用 户 组: 普通用户
  • 注册时间: 2015-10-28 20:06
文章分类

全部博文(14)

文章存档

2016年(8)

2015年(7)

我的朋友

分类: Android平台

2016-08-23 18:29:03

  常用的TabHost实现方式有两种:一种是继承TabActivity,另一种是不继承。现就两种方式实现一下:
 1.不继承TabActivity
 activity_main.xml文件

点击(此处)折叠或打开

  1. <LinearLayout xmlns:android=""
  2.     xmlns:tools=""
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical"
  6.     tools:context="com.example.tabhostpractice.MainActivity">

  7.     <TabHost
  8.         android:id="@+id/tabhost"
  9.         android:layout_width="match_parent"
  10.         android:layout_height="match_parent">

  11.         <TabWidget
  12.             android:id="@android:id/tabs"
  13.             android:layout_width="match_parent"
  14.             android:layout_height="wrap_content"
  15.             ></TabWidget>
  16.         <FrameLayout
  17.             android:id="@android:id/tabcontent"
  18.             android:layout_width="match_parent"
  19.             android:layout_height="match_parent"
  20.             ></FrameLayout>
  21.     </TabHost>
  22. </LinearLayout>
  在这个TabHost中有两个标签,对应的两个标签页用两个xml文件来实现
  layout11.xml

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android=""
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:id="@+id/layout1"
  6.     android:gravity="center"
  7.     android:orientation="vertical">

  8.     <TextView
  9.         android:layout_width="wrap_content"
  10.         android:layout_height="wrap_content"
  11.         android:textSize="30sp"
  12.         android:text="this is first" />
  13. </LinearLayout>
  layout22.xml

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android=""
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:id="@+id/layout2"
  6.     android:gravity="center"
  7.     android:orientation="vertical">

  8.     <TextView
  9.         android:layout_width="wrap_content"
  10.         android:layout_height="wrap_content"
  11.         android:textSize="30sp"
  12.         android:text="this is two" />
  13. </LinearLayout>
主文件

点击(此处)折叠或打开

  1. public class MainActivity extends AppCompatActivity {
  2.     TabHost mTabhost;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.activity_main);

  7.         mTabhost = (TabHost) findViewById(R.id.tabhost);
  8.         mTabhost.setup();

  9.         LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
  10.         inflater.inflate(R.layout.layout11,mTabhost.getTabContentView());
  11.         inflater.inflate(R.layout.layout22,mTabhost.getTabContentView());


  12.         TabHost.TabSpec spec1 = mTabhost.newTabSpec("11");
  13.         spec1.setIndicator("first");
  14.         spec1.setContent(R.id.layout1);

  15.         TabHost.TabSpec spec2 = mTabhost.newTabSpec("22");
  16.         spec2.setIndicator("two");
  17.         spec2.setContent(R.id.layout2);

  18.         mTabhost.addTab(spec1);
  19.         mTabhost.addTab(spec2);
  20.     }
  21. }
  其中11和22是tabId,在标签页切换时,调用的onTabChanged(String tabId)中会用到。若想为每个标签添加图片,可用spec1.setIndicator()来实现;若想让标签实现特殊的布局,可另建一个xml文件来实现布局,详细见下面的另一个例子。
 
  另外,也可以直接在TabHost控件所在的xml文件中直接设置tab的布局内容,这样在主文件中不用再动态加载xml文件了,一些简易的布局时,可以这样实现。

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android=""
  3.     xmlns:tools=""
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:orientation="vertical"
  7.     tools:context="com.example.tabhostpractice.MainActivity">

  8.     <TabHost
  9.         android:id="@+id/tabhost"
  10.         android:layout_width="match_parent"
  11.         android:layout_height="match_parent">

  12.         <LinearLayout
  13.             android:layout_width="match_parent"
  14.             android:layout_height="match_parent"
  15.             android:orientation="vertical">

  16.             <TabWidget
  17.                 android:id="@android:id/tabs"
  18.                 android:layout_width="match_parent"
  19.                 android:layout_height="wrap_content"></TabWidget>

  20.             <FrameLayout
  21.                 android:id="@android:id/tabcontent"
  22.                 android:layout_width="match_parent"
  23.                 android:layout_height="match_parent">

  24.                 <!-- 第一个tab的布局 -->
  25.                 <LinearLayout
  26.                     android:id="@+id/tab1"
  27.                     android:layout_width="match_parent"
  28.                     android:layout_height="match_parent">

  29.                     <TextView
  30.                         android:id="@+id/textView1"
  31.                         android:layout_width="wrap_content"
  32.                         android:layout_height="wrap_content"
  33.                         android:text="this is first" />

  34.                 </LinearLayout>

  35.                 <!-- 第二个tab的布局 -->
  36.                 <LinearLayout
  37.                     android:id="@+id/tab2"
  38.                     android:layout_width="match_parent"
  39.                     android:layout_height="match_parent">

  40.                     <TextView
  41.                         android:id="@+id/textView2"
  42.                         android:layout_width="wrap_content"
  43.                         android:layout_height="wrap_content"
  44.                         android:text="this is two" />

  45.                 </LinearLayout>

  46.                 <!-- 第三个tab的布局 -->
  47.                 <LinearLayout
  48.                     android:id="@+id/tab0"
  49.                     android:layout_width="match_parent"
  50.                     android:layout_height="match_parent">

  51.                     <TextView
  52.                         android:id="@+id/textView0"
  53.                         android:layout_width="wrap_content"
  54.                         android:layout_height="wrap_content"
  55.                         android:text="this is three" />
  56.                 </LinearLayout>

  57.             </FrameLayout>
  58.         </LinearLayout>
  59.     </TabHost>
  60. </LinearLayout>
  这种情况,在预览区就可以看到真正运行时在第一个tab时的样子,而tab的标题为每个布局的id,三个tab标题依次为:tab1,tab2,tab0。

点击(此处)折叠或打开

  1. public class MainActivity extends AppCompatActivity {
  2.     TabHost mTabhost;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.activity_main);

  7.         mTabhost = (TabHost)findViewById(R.id.tabhost);
  8.         mTabhost.setup();
  9.         
  10.         TabHost.TabSpec spec1 = mTabhost.newTabSpec("11");
  11.         spec1.setIndicator("first");
  12.         spec1.setContent(R.id.tab1);

  13.         TabHost.TabSpec spec2 = mTabhost.newTabSpec("22");
  14.         spec2.setIndicator("two");
  15.         spec2.setContent(R.id.tab2);

  16.         TabHost.TabSpec spec3 = mTabhost.newTabSpec("00");
  17.         spec3.setIndicator("three");
  18.         spec3.setContent(R.id.tab0);


  19.         mTabhost.addTab(spec1);
  20.         mTabhost.addTab(spec2);
  21.         mTabhost.addTab(spec3);
  22.     }
  23. }
 
2.继承自TabActivity
 在此不用在xml文件中使用TabHost控件了,而是使用android内部定义好的tab_content.xml ,也就是在代码中使用getTabHost(),其后台源码如下:

点击(此处)折叠或打开

  1. public TabHost getTabHost() {
  2.         ensureTabHost();
  3.         return mTabHost;
  4.     }

  5.  private void ensureTabHost() {
  6.         if (mTabHost == null) {
  7.             this.setContentView(com.android.internal.R.layout.tab_content);
  8.         }
  9.   }
  而其内部的tab_content.xml文件为:

点击(此处)折叠或打开

  1. <TabHost
  2.     xmlns:android=""
  3.     android:id="@android:id/tabhost"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent">

  6.     <LinearLayout
  7.         android:orientation="vertical"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="match_parent">

  10.         <TabWidget
  11.             android:id="@android:id/tabs"
  12.             android:orientation="horizontal"
  13.             android:layout_width="match_parent"
  14.             android:layout_height="wrap_content"
  15.             android:layout_weight="0"/>

  16.         <FrameLayout
  17.             android:id="@android:id/tabcontent"
  18.             android:layout_width="match_parent"
  19.             android:layout_height="0dip"
  20.             android:layout_weight="1"/>

  21.     </LinearLayout>
  22. </TabHost>
  发现整个过程和上面不继承TabActivity时相。还按照上面的情况,在两个xml文件中定义两个tab内容,由于在使用getTabHost()时,已经调用了SetContentView(),所以在下面的主文件中,就不用调用了。
 layout11.xml和layout22.xml文件和上面一样,在这就不在列出。
 主文件MainActivity.java如下:

点击(此处)折叠或打开

  1. public class MainActivity extends TabActivity {
  2.     TabHost mTabhost;

  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);

  6.         mTabhost = getTabHost();

  7.         LayoutInflater inflater = LayoutInflater.from(this);

  8.         inflater.inflate(R.layout.layout11, mTabhost.getTabContentView());
  9.         inflater.inflate(R.layout.layout22, mTabhost.getTabContentView()); //动态载入XML


  10.         TabHost.TabSpec spec1 = mTabhost.newTabSpec("11");
  11.         spec1.setIndicator("first");
  12.         spec1.setContent(R.id.layout1);

  13.         TabHost.TabSpec spec2 = mTabhost.newTabSpec("22");
  14.         spec2.setIndicator("two");
  15.         spec2.setContent(R.id.layout2);

  16.         mTabhost.addTab(spec1);
  17.         mTabhost.addTab(spec2);
  18.     }
  19. }
  运行结果显示和上面一样,只不过由于由于一个是继承AppCompatActivit(默认带导航栏)和一个是继承TabHost的缘故,造成了导航栏有无的区别。
                         

 3.搞清了TabHost的基础知识,就可以用它扩展实现一个底部导航功能。在这主要是为了学习OsChina客户端源码,下面是效果图:
  整个实现是按照源码摘出来的,主要用到了FragmentTabHost,也用到枚举类来初始化Tab标签,另外,indicator的实现用到了xml布局样本,在此仅列出部分主要代码。
 MainTab.java

点击(此处)折叠或打开

  1. package com.example.myapplication;

  2. public enum MainTab {

  3.      NEWS(0, "综合", R.drawable.tab_icon_new, fragment1.class),

  4.      TWEET(1, "动弹", R.drawable.tab_icon_tweet, fragment2.class),

  5.      QUICK(2, "快速", R.drawable.tab_icon_new, null),

  6.      EXPLORE(3, "发现", R.drawable.tab_icon_explore, fragment3.class),

  7.      ME(4, "我", R.drawable.tab_icon_me, fragment4.class);

  8.      private int idx;
  9.      private String resName;
  10.      private int resIcon;
  11.      private Class<?> clz;

  12.      private MainTab(int idx, String resName, int resIcon, Class<?> clz) {
  13.      this.idx = idx;
  14.      this.resName = resName;
  15.      this.resIcon = resIcon;
  16.      this.clz = clz;
  17.      }
  18.      public int getIdx() {
  19.      return idx;
  20.      }
  21.      public void setIdx(int idx) {
  22.      this.idx = idx;
  23.      }
  24.      public String getResName() {
  25.      return resName;
  26.      }
  27.      public void setResName(String resName) {
  28.      this.resName = resName;
  29.      }
  30.      public int getResIcon() {
  31.      return resIcon;
  32.      }
  33.      public void setResIcon(int resIcon) {
  34.      this.resIcon = resIcon;
  35.      }
  36.      public Class<?> getClz() {
  37.      return clz;
  38.      }
  39.      public void setClz(Class<?> clz) {
  40.      this.clz = clz;
  41.      }
  42.     }
  activity.xml,在这有一处不解 MyFragmentTabHost的id不能写为@android:id/tabhost,但源码确实是这样实现的,具体原因回头再找出吧。

点击(此处)折叠或打开

  1. <LinearLayout xmlns:android=""
  2.     xmlns:tools=""
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical">

  6.     <FrameLayout
  7.         android:id="@+id/realtabcontent"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="0dp"
  10.         android:layout_weight="1"></FrameLayout>

  11.     <FrameLayout
  12.         android:layout_width="match_parent"
  13.         android:layout_height="wrap_content"
  14.         android:background="#ffffff">

  15.         <RelativeLayout
  16.             android:layout_width="match_parent"
  17.             android:layout_height="wrap_content"
  18.             >

  19.             <com.example.myapplication.MyFragmentTabHost
  20.                 android:id="@+id/tabhost"
  21.                 android:layout_width="match_parent"
  22.                 android:layout_height="wrap_content"
  23.                 android:layout_marginTop="4dp">
  24.             </com.example.myapplication.MyFragmentTabHost>

  25.             <View
  26.                 android:layout_width="match_parent"
  27.                 android:layout_height="1px"
  28.                 android:background="#D6D6D6" />
  29.         </RelativeLayout>

  30.         <ImageView
  31.             android:id="@+id/quick_option_iv"
  32.             android:layout_width="40dp"
  33.             android:layout_height="40dp"
  34.             android:layout_gravity="center"
  35.             android:layout_marginBottom="4dp"
  36.             android:layout_marginTop="4dp"
  37.             android:contentDescription="@null"
  38.             android:src="@drawable/btn_quickoption_selector" />
  39.     </FrameLayout>
  40. </LinearLayout>







阅读(564) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~