今天讲一下,如何在TabHost中,再放TabHost。
先来看一下效果。
一层TabHost
两层Tabhost (内部TabHots在上面)
两层TabHost (内层TabHots在下面)
下面说一下代码,一共3个 java类,3个xml布局文件。
看一下主画面:
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" -
android:background="@drawable/default_bg"> -
<LinearLayout android:orientation="vertical" -
android:layout_width="fill_parent" android:layout_height="fill_parent"> -
<TabWidget android:id="@android:id/tabs" -
android:layout_alignParentBottom="true" android:layout_width="fill_parent" -
android:layout_height="wrap_content"/> -
<FrameLayout android:id="@android:id/tabcontent" -
android:layout_weight="1" android:layout_width="fill_parent" -
android:layout_height="fill_parent" /> -
</LinearLayout> - </TabHost>
就是常规的Tabhost布局。
入口类:
DoubleTabHost.java
- package
com.yfz; - import
android.app.TabActivity; - import
android.content.Intent; - import
android.os.Bundle; - import
android.widget.TabHost; -
- public
class DoubleTabHost extends TabActivity { -
-
-
-
-
@Override -
public void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
setContentView(R.layout.main); -
-
TabHost mTabHost = getTabHost(); -
mTabHost.addTab(mTabHost.newTabSpec("Twitter").setIndicator( -
"Twitter", -
getResources().getDrawable(android.R.drawable.arrow_down_float)).setContent( -
new Intent(this, SubTab.class))); -
mTabHost.addTab(mTabHost.newTabSpec("Facebook").setIndicator( -
"Facebook", -
getResources().getDrawable(android.R.drawable.arrow_down_float)).setContent( -
new Intent(this, NormalActivity.class))); -
mTabHost.setCurrentTab(0); -
} - }
对于TabHost、布局文件中必须包含TabHost、TabWidget 、FrameLayout .缺一不可
如果加载该TabHost画面的类继承TabActivity,并且想通过getTabHost()方法来获取TabHost,getTabWidget()方法获取TabWidget,
那么TabHost、TabWidget 、FrameLayout
否则会报运行时异常,错误如下:
TabHost ID错误:
- ERROR/AndroidRuntime(8301):
Caused by: java.lang.RuntimeException: Your content must have a TabHost whose id attribute is 'android.R.id.tabhost'
TabWidget ID 错误:
- ERROR/AndroidRuntime(8354):
Caused by: java.lang.RuntimeException: Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'
FrameLayout
- ERROR/AndroidRuntime(8404):
Caused by: java.lang.RuntimeException: Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'
子TabHost页面:
subtab.xml
- <?xml
version="1.0" encoding="utf-8"?> - <TabHost
xmlns:android="http://schemas.android.com/apk/res/android" -
android:id="@+id/mytabhost" android:layout_width="fill_parent" -
android:layout_height="fill_parent" -
android:background="@drawable/default_bg"> -
<LinearLayout android:orientation="vertical" -
android:layout_width="fill_parent" android:layout_height="fill_parent"> -
<!-- 注意FrameLayout/TabWidget标签的位置--> -
<FrameLayout android:id="@android:id/tabcontent" -
android:layout_weight="1" android:layout_width="fill_parent" -
android:layout_height="fill_parent" > -
<TextView -
android:id="@+id/widget59" -
android:layout_width="wrap_content" -
android:layout_height="wrap_content" -
android:text="你在想什么?" -
android:layout_alignParentTop="true" -
android:layout_centerHorizontal="true" -
> -
</TextView> -
<TextView -
android:id="@+id/widget60" -
android:layout_width="wrap_content" -
android:layout_height="wrap_content" -
android:text="我在想Android" -
android:layout_alignParentTop="true" -
android:layout_alignParentRight="true" -
> -
</TextView> -
</FrameLayout> -
<TabWidget android:id="@android:id/tabs" -
android:layout_alignParentBottom="true" android:layout_width="fill_parent" -
android:layout_height="wrap_content"/> -
</LinearLayout> - </TabHost>
子TabHost页面加载类:
SubTab.java
- package
com.yfz; - import
android.app.Activity; - import
android.os.Bundle; - import
android.widget.TabHost; - import
android.widget.TabWidget; - import
android.widget.TextView; -
- public
class SubTab extends Activity { -
-
@Override -
public void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
setContentView(R.layout.subtab); -
-
//以下三句代码,注意顺序 -
TabHost mTabHost = (TabHost)findViewById(R.id.mytabhost); -
mTabHost.setup(); -
TabWidget tabWidget = mTabHost.getTabWidget(); -
-
mTabHost.addTab(mTabHost.newTabSpec("苏州").setIndicator( -
"苏州").setContent(R.id.widget59)); -
mTabHost.addTab(mTabHost.newTabSpec("上海").setIndicator( -
"上海").setContent(R.id.widget60)); -
mTabHost.addTab(mTabHost.newTabSpec("天津").setIndicator( -
"天津").setContent(R.id.widget60)); -
mTabHost.addTab(mTabHost.newTabSpec("北京").setIndicator( -
"北京").setContent(R.id.widget60)); -
mTabHost.setCurrentTab(0); -
-
int height =30; - //
int width =45; -
-
for (int i =0; i < tabWidget.getChildCount(); i++) { -
-
-
tabWidget.getChildAt(i).getLayoutParams().height = height; - //
tabWidget.getChildAt(i).getLayoutParams().width = width; -
-
final TextView tv = (TextView) tabWidget.getChildAt(i).findViewById(android.R.id.title); -
tv.setTextColor(this.getResources().getColorStateList(android.R.color.white)); -
} -
} - }
如果加载TabHost画面的继承自Activity,可以通过findViewById来获取这三个组件,此时ID可自定义。
需要注意的是,此时必须调用setup方法来加载TabHost。
对了,不要忘了在AndroidManifest.xml定义Activity~~呵呵!
要点就这么多~ 就这样了。
源码我会上传,地址稍后给出。
源程序下载地址:
BUG对应。
问题一:无法在子tabhost中打开Activity。
- java.lang.IllegalStateException:
Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?
解决办法1:
1. 将初始化tabHost的那个类(此例中为SubTab类),继承ActivityGroup,而不是Activity
2. tabhost.setup() 改为
具体参考:
http://hi.baidu.com/ljlkings/blog/item/47f1afdbdcd27de638012f76
解决办法2:
也可以将SubTab类改继承TabActivity,然后布局文件中Tabhost的id改为@android:id/tabhost.
因为TabActivity也是继承自ActivitGroup的。
以上两种方法都可以。
问题二:
- 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) =>