(转载)【Android进阶】嵌套TabHo…

今天讲一下,如何在TabHost中,再放TabHost。

 

先来看一下效果。

 

一层TabHost

 

 

两层Tabhost (内部TabHots在上面)

 

两层TabHost (内层TabHots在下面)

 

 

 

下面说一下代码,一共3个 java类,3个xml布局文件。

 

看一下主画面:

main.xml

 

[xhtml]  view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TabHost xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@android:id/tabhost" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@drawable/default_bg">  
  6.     <LinearLayout android:orientation="vertical"   
  7.         android:layout_width="fill_parent" android:layout_height="fill_parent">  
  8.         <TabWidget android:id="@android:id/tabs"  
  9.             android:layout_alignParentBottom="true" android:layout_width="fill_parent"  
  10.             android:layout_height="wrap_content"/>  
  11.         <FrameLayout android:id="@android:id/tabcontent"  
  12.             android:layout_weight="1" android:layout_width="fill_parent"  
  13.             android:layout_height="fill_parent" />  
  14.     </LinearLayout>  
  15. </TabHost>  

 

 

就是常规的Tabhost布局。

 

入口类:

DoubleTabHost.java

 

[java]  view plain copy print ?
  1. package com.yfz;  
  2. import android.app.TabActivity;  
  3. import android.content.Intent;  
  4. import android.os.Bundle;  
  5. import android.widget.TabHost;  
  6.   
  7. public class DoubleTabHost extends TabActivity  
  8.       
  9.        
  10.       
  11.       
  12.     @Override  
  13.     public void onCreate(Bundle savedInstanceState)  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.main);  
  16.           
  17.         TabHost mTabHost getTabHost();  
  18.         mTabHost.addTab(mTabHost.newTabSpec("Twitter").setIndicator(  
  19.                 "Twitter" 
  20.                 getResources().getDrawable(android.R.drawable.arrow_down_float)).setContent(  
  21.                 new Intent(thisSubTab.class)));  
  22.         mTabHost.addTab(mTabHost.newTabSpec("Facebook").setIndicator(  
  23.                 "Facebook" 
  24.                 getResources().getDrawable(android.R.drawable.arrow_down_float)).setContent(  
  25.                 new Intent(thisNormalActivity.class)));  
  26.         mTabHost.setCurrentTab(0);  
  27.      
  28.  

 

 

 

对于TabHost、布局文件中必须包含TabHost、TabWidget 、FrameLayout .缺一不可

如果加载该TabHost画面的类继承TabActivity,并且想通过getTabHost()方法来获取TabHost,getTabWidget()方法获取TabWidget,

那么TabHost、TabWidget 、FrameLayout 三者的ID必须是android.R.id.tabhost、android.R.id.tabs、android.R.id.tabcontent

 

 

否则会报运行时异常,错误如下:

TabHost ID错误:

 

[xhtml]  view plain copy print ?
  1. ERROR/AndroidRuntime(8301): Caused by: java.lang.RuntimeException: Your content must have TabHost whose id attribute is 'android.R.id.tabhost'  

 

 

TabWidget ID 错误:

 

[xhtml]  view plain copy print ?
  1. ERROR/AndroidRuntime(8354): Caused by: java.lang.RuntimeException: Your TabHost must have TabWidget whose id attribute is 'android.R.id.tabs'  

 

 

FrameLayout  ID错误:

 

[xhtml]  view plain copy print ?
  1. ERROR/AndroidRuntime(8404): Caused by: java.lang.RuntimeException: Your TabHost must have FrameLayout whose id attribute is 'android.R.id.tabcontent'  

 

 

 

子TabHost页面:

subtab.xml

 

[xhtml]  view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TabHost xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/mytabhost" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@drawable/default_bg">  
  6.     <LinearLayout android:orientation="vertical"   
  7.         android:layout_width="fill_parent" android:layout_height="fill_parent">  
  8.         <!-- 注意FrameLayout/TabWidget标签的位置-->  
  9.         <FrameLayout android:id="@android:id/tabcontent"  
  10.             android:layout_weight="1" android:layout_width="fill_parent"  
  11.             android:layout_height="fill_parent" >  
  12.                 <TextView  
  13.                     android:id="@+id/widget59"  
  14.                     android:layout_width="wrap_content"  
  15.                     android:layout_height="wrap_content"  
  16.                     android:text="你在想什么?"  
  17.                     android:layout_alignParentTop="true"  
  18.                     android:layout_centerHorizontal="true"  
  19.                     >  
  20.                     </TextView>  
  21.                     <TextView  
  22.                     android:id="@+id/widget60"  
  23.                     android:layout_width="wrap_content"  
  24.                     android:layout_height="wrap_content"  
  25.                     android:text="我在想Android"  
  26.                     android:layout_alignParentTop="true"  
  27.                     android:layout_alignParentRight="true"  
  28.                     >  
  29.                     </TextView>  
  30.         </FrameLayout>  
  31.         <TabWidget android:id="@android:id/tabs"  
  32.             android:layout_alignParentBottom="true" android:layout_width="fill_parent"  
  33.             android:layout_height="wrap_content"/>  
  34.     </LinearLayout>  
  35. </TabHost>  

 

 

子TabHost页面加载类:

SubTab.java

 

[java]  view plain copy print ?
  1. package com.yfz;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.widget.TabHost;  
  5. import android.widget.TabWidget;  
  6. import android.widget.TextView;  
  7.   
  8. public class SubTab extends Activity  
  9.       
  10.     @Override  
  11.     public void onCreate(Bundle savedInstanceState)  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.subtab);  
  14.           
  15.         //以下三句代码,注意顺序  
  16.         TabHost mTabHost (TabHost)findViewById(R.id.mytabhost);  
  17.         mTabHost.setup();  
  18.         TabWidget tabWidget mTabHost.getTabWidget();  
  19.           
  20.         mTabHost.addTab(mTabHost.newTabSpec("苏州").setIndicator(  
  21.                 "苏州").setContent(R.id.widget59));  
  22.         mTabHost.addTab(mTabHost.newTabSpec("上海").setIndicator(  
  23.                 "上海").setContent(R.id.widget60));  
  24.         mTabHost.addTab(mTabHost.newTabSpec("天津").setIndicator(  
  25.                 "天津").setContent(R.id.widget60));  
  26.         mTabHost.addTab(mTabHost.newTabSpec("北京").setIndicator(  
  27.                 "北京").setContent(R.id.widget60));  
  28.         mTabHost.setCurrentTab(0);  
  29.           
  30.         int height =30  
  31. //      int width =45;   
  32.               
  33.         for (int =0tabWidget.getChildCount(); i++)  
  34.               
  35.                
  36.             tabWidget.getChildAt(i).getLayoutParams().height height;   
  37. //            tabWidget.getChildAt(i).getLayoutParams().width width;   
  38.                
  39.              final TextView tv (TextView) tabWidget.getChildAt(i).findViewById(android.R.id.title);   
  40.              tv.setTextColor(this.getResources().getColorStateList(android.R.color.white));   
  41.          
  42.      
  43.  

 

 

如果加载TabHost画面的继承自Activity,可以通过findViewById来获取这三个组件,此时ID可自定义。

需要注意的是,此时必须调用setup方法来加载TabHost。

 

对了,不要忘了在AndroidManifest.xml定义Activity~~呵呵!

 

要点就这么多~ 就这样了。

 

 

 

源码我会上传,地址稍后给出。

 

源程序下载地址:   http://download.csdn.net/source/3037680  

 

 

 


 

BUG对应。  感谢simayilong 和 gz116 提出这两个典型问题。

 

问题一:无法在子tabhost中打开Activity。

 

[java]  view plain copy print ?
  1. java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)' 

 

解决办法1:

1. 将初始化tabHost的那个类(此例中为SubTab类),继承ActivityGroup,而不是Activity

2. tabhost.setup() 改为 tabHost.setup(this.getLocalActivityManager());

 

具体参考:

http://stackoverflow.com/questions/3272500/android-exception-did-you-forget-to-call-public-void-setup-localactivitymanage

 

http://hi.baidu.com/ljlkings/blog/item/47f1afdbdcd27de638012f76.html

 

解决办法2:

也可以将SubTab类改继承TabActivity,然后布局文件中Tabhost的id改为@android:id/tabhost.

因为TabActivity也是继承自ActivitGroup的。

 

以上两种方法都可以。

 

问题二:  TabHost 嵌套后,Dialog 不能显示

 

 

[java]  view plain copy print ?
  1. android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@43e57e20 is not valid; is your activity running?  

 

 

解决办法:

AlertDialog.Builder(xxx.this) => AlertDialog.Builder(xxx.this.getParent()) 

    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值