嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
2012-03-16 17:02
375 查看
今天讲一下,如何在TabHost中,再放TabHost。
先来看一下效果。
一层TabHost
两层Tabhost (内部TabHots在上面)
两层TabHost (内层TabHots在下面)
下面说一下代码,一共3个 java类,3个xml布局文件。
看一下主画面:
main.xml
源码copy to clipboard打印?
<?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>
<?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
源码copy to clipboard打印?
package com.yfz;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;
/**
* 本类继承了TabActivity
* @author Administrator
*
*/
public class DoubleTabHost extends TabActivity {
/* 注意:
* 对于TabHost、布局文件中必须包含
* TabHost、TabWidget 、FrameLayout
* 如果继承TabActivity,并且通过getTabHost()方法来获取TabHost
* 那么三者的ID必须是android.R.id.tabhost、android.R.id.tabs、android.R.id.tabcontent
*
* 如果继承Activity,可以通过findViewById来获取这三个组件,此时ID可自定义
*/
/** Called when the activity is first created. */
@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);
}
}
package com.yfz; import android.app.TabActivity; import android.content.Intent; import android.os.Bundle; import android.widget.TabHost; /** * 本类继承了TabActivity * @author Administrator * */ public class DoubleTabHost extends TabActivity { /* 注意: * 对于TabHost、布局文件中必须包含 * TabHost、TabWidget 、FrameLayout * 如果继承TabActivity,并且通过getTabHost()方法来获取TabHost * 那么三者的ID必须是android.R.id.tabhost、android.R.id.tabs、android.R.id.tabcontent * * 如果继承Activity,可以通过findViewById来获取这三个组件,此时ID可自定义 */ /** Called when the activity is first created. */ @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 三者的ID必须是android.R.id.tabhost、android.R.id.tabs、android.R.id.tabcontent
否则会报运行时异常,错误如下:
TabHost ID错误:
源码copy to clipboard打印?
ERROR/AndroidRuntime(8301): Caused by: java.lang.RuntimeException: Your content must have a TabHost whose id attribute is 'android.R.id.tabhost'
ERROR/AndroidRuntime(8301): Caused by: java.lang.RuntimeException: Your content must have a TabHost whose id attribute is 'android.R.id.tabhost'
TabWidget ID 错误:
源码copy to clipboard打印?
ERROR/AndroidRuntime(8354): Caused by: java.lang.RuntimeException: Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'
ERROR/AndroidRuntime(8354): Caused by: java.lang.RuntimeException: Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'
FrameLayout ID错误:
源码copy to clipboard打印?
ERROR/AndroidRuntime(8404): Caused by: java.lang.RuntimeException: Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'
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
源码copy to clipboard打印?
<?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>
<?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
源码copy to clipboard打印?
package com.yfz;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
/**
*
* @author Administrator
*
*/
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++) {
/**设置高度、宽度,由于宽度设置为fill_parent,在此对它没效果 */
tabWidget.getChildAt(i).getLayoutParams().height = height;
// tabWidget.getChildAt(i).getLayoutParams().width = width;
/**设置tab中标题文字的颜色,不然默认为黑色 */
final TextView tv = (TextView) tabWidget.getChildAt(i).findViewById(android.R.id.title);
tv.setTextColor(this.getResources().getColorStateList(android.R.color.white));
}
}
}
package com.yfz; import android.app.Activity; import android.os.Bundle; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; /** * * @author Administrator * */ 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++) { /**设置高度、宽度,由于宽度设置为fill_parent,在此对它没效果 */ tabWidget.getChildAt(i).getLayoutParams().height = height; // tabWidget.getChildAt(i).getLayoutParams().width = width; /**设置tab中标题文字的颜色,不然默认为黑色 */ 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~~呵呵!
要点就这么多~ 就这样了。
源码我会上传,地址稍后给出。
源程序下载地址: http://download.csdn.net/source/3037680
BUG对应。 感谢simayilong 和 gz116 提出这两个典型问题。
问题一:无法在子tabhost中打开Activity。
源码copy to clipboard打印?
java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?
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 不能显示
源码copy to clipboard打印?
android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@43e57e20 is not valid; is your activity running?
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())
原文链接:http://blog.csdn.net/feng88724/article/details/6203358
标签: <无>
补充话题说明»
相关文章推荐
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树)
- 原创 【Android进阶】嵌套TabHost (TabHost中放TabHost,类似二级目录、二级树) 收藏
- javascript制作省市联动等类似二级目录
- 如何查看二级目录是否被收录
- nginx 不同目录静态资源位置 通过二级目录(路径)映射不同的反向代理
- 编写一个含二级目录的源码(Asp+JavaScript)
- linux下关于Apache设置二级域名绑定二级目录的方法
- nginx 配置访问二级目录
- Nginx通过二级目录(路径)映射不同的反向代理,规避IP+端口访问
- 在sae中,怎么将图片上传到storage的二级目录的代码?
- Windows上创建类似Unix的home目录
- IT连创业系列:近期功能调整(小魔术功能从二级目录调整到一级栏目)
- 使用OpenCV读、操作、写图像并与bash合作对某个目录下所有图像进行类似处理
- Fragment简单介绍及其类似与tabhost的底部实现例子