转自http://blog.csdn.net/chenzheng_java/article/details/6208020

一:不继承TabActivity并以布局文件进行布局


android tabHost布局 大全_第1张图片

上图为最终效果图

代码结构图

android tabHost布局 大全_第2张图片

main.xml

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/hometabs"
  4. android:orientation="vertical"
  5. android:layout_width="fill_parent"
  6. android:layout_height="fill_parent">
  7. <!--TabHost必须包含一个TabWidget和一个FrameLayout-->
  8. <TabHostandroid:id="@+id/tabhost"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. >
  12. <LinearLayout
  13. android:orientation="vertical"
  14. android:layout_width="fill_parent"
  15. android:layout_height="fill_parent">
  16. <!--TabWidget的id属性必须为@android:id/tabs-->
  17. <TabWidgetandroid:id="@android:id/tabs"
  18. android:orientation="horizontal"
  19. android:layout_width="fill_parent"
  20. android:layout_height="wrap_content">
  21. </TabWidget>
  22. <!--FrameLayout的id属性必须为@android:id/tabcontent-->
  23. <FrameLayoutandroid:id="@android:id/tabcontent"
  24. android:layout_width="fill_parent"
  25. android:layout_height="fill_parent">
  26. <TextViewandroid:id="@+id/view1"
  27. android:layout_width="fill_parent"
  28. android:layout_height="fill_parent"/>
  29. <TextViewandroid:id="@+id/view2"
  30. android:layout_width="fill_parent"
  31. android:layout_height="fill_parent"/>
  32. <TextViewandroid:id="@+id/view3"
  33. android:layout_width="fill_parent"
  34. android:layout_height="fill_parent"/>
  35. </FrameLayout>
  36. </LinearLayout>
  37. </TabHost>
  38. </LinearLayout>

java代码如下

[java] view plain copy
  1. packagecn.com.tagHost.test;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.widget.TabHost;
  5. importandroid.widget.TabWidget;
  6. publicclassTagHostTest2extendsActivity{
  7. @Override
  8. publicvoidonCreate(BundlesavedInstanceState){
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.main);
  11. //获取TabHost对象
  12. TabHosttabHost=(TabHost)findViewById(R.id.tabhost);
  13. //如果没有继承TabActivity时,通过该种方法加载启动tabHost
  14. tabHost.setup();
  15. tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("第一个标签",
  16. getResources().getDrawable(R.drawable.icon)).setContent(
  17. R.id.view1));
  18. tabHost.addTab(tabHost.newTabSpec("tab3").setIndicator("第三个标签")
  19. .setContent(R.id.view3));
  20. tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("第二个标签")
  21. .setContent(R.id.view2));
  22. }
  23. }

运行得到正确的结果。

废话连篇:这里需要注意的是

第一:布局文件的格式。以及TabWidget和FrameLayout的id属性值。

第二:TabWidget代表的是标签部分,FrameLayout代表的点击标签后看到的内容部分。FrameLayout里面声明的组件意为具备成为标签内容的资格,具体的还要在代码中具体指定。

你是否也想要这种结果呢。让标签在下部分显示

android tabHost布局 大全_第3张图片

那么你只需要给main.xml进行下布局修改就可以了。

main.xml

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/hometabs"android:orientation="vertical"
  4. android:layout_width="fill_parent"android:layout_height="fill_parent">
  5. <!--TabHost必须包含一个TabWidget和一个FrameLayout-->
  6. <TabHostandroid:id="@+id/tabhost"android:layout_width="fill_parent"
  7. android:layout_height="wrap_content">
  8. <LinearLayoutandroid:orientation="vertical"
  9. android:layout_width="fill_parent"android:layout_height="fill_parent">
  10. <!--FrameLayout的id属性必须为@android:id/tabcontent-->
  11. <FrameLayoutandroid:id="@android:id/tabcontent"
  12. android:layout_width="fill_parent"android:layout_height="fill_parent">
  13. <TextViewandroid:id="@+id/view1"android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. android:text="hellobaby!"
  16. />
  17. <TextViewandroid:id="@+id/view2"android:layout_width="fill_parent"
  18. android:layout_height="fill_parent"/>
  19. <TextViewandroid:id="@+id/view3"android:layout_width="fill_parent"
  20. android:layout_height="fill_parent"/>
  21. </FrameLayout>
  22. <RelativeLayoutandroid:layout_width="fill_parent"
  23. android:layout_height="fill_parent">
  24. <!--TabWidget的id属性必须为@android:id/tabs-->
  25. <TabWidgetandroid:id="@android:id/tabs"
  26. android:orientation="horizontal"android:layout_width="fill_parent"
  27. android:layout_height="wrap_content"
  28. android:layout_alignParentBottom="true"
  29. android:paddingBottom="0dp"
  30. >
  31. </TabWidget>
  32. </RelativeLayout>
  33. </LinearLayout>
  34. </TabHost>
  35. </LinearLayout>

为了让标签和父容器底部持平,我们使用了android:layout_alignParentBottom="true",该属性只有在RelativeLayout布局中才会存在哦、这也是为什么我们将tabWidget放入一个RelativeLayout中的原因。

此外,在lineaerLayout布局中,TabWidget和FrameLayout的位置可是调换了哦。


继承TabActivity并以activity布局


果图:android tabHost布局 大全_第4张图片

再看下代码结构:

android tabHost布局 大全_第5张图片

其中black.gif顾名思义就是一个黑背景图片,grey.gif就是一张灰色的背景图片

然后直接上代码:

ArtistActivity.java

[java] view plain copy
  1. packagecn.com.tagview;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.widget.TextView;
  5. publicclassArtistActivityextendsActivity{
  6. @Override
  7. protectedvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. TextViewtextView=newTextView(this);
  10. //该文档将会作为标签的内容进行显示
  11. textView.setText("艺术内容");
  12. setContentView(textView);
  13. }
  14. }

MusicActivity.java

[java] view plain copy
  1. packagecn.com.tagview;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.widget.TextView;
  5. publicclassMusicActivityextendsActivity{
  6. @Override
  7. protectedvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. TextViewtextView=newTextView(this);
  10. //该文档将会作为标签的内容进行显示
  11. textView.setText("音乐内容");
  12. setContentView(textView);
  13. }
  14. }

SportActivity.java

[java] view plain copy
  1. packagecn.com.tagview;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.widget.TextView;
  5. publicclassSportActivityextendsActivity{
  6. @Override
  7. protectedvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. TextViewtextView=newTextView(this);
  10. //该文档将会作为标签的内容进行显示
  11. textView.setText("运动内容");
  12. setContentView(textView);
  13. }
  14. }

ArtistActivity.java MusicActivity.java SportActivity.java三个activity是用做标签内容的activity。即当用户点击相应的标签时,下边会显示相应的activity内容。

ic_tab.xml代码

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <selector
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. >
  5. <itemandroid:drawable="@drawable/grey"
  6. android:state_selected="true"
  7. ></item>
  8. <itemandroid:drawable="@drawable/black"
  9. ></item>
  10. </selector>

这里一定要注意ic_tab.xml文件的位置,是放在res/drawable文件夹下的。有些朋友说怎么没有这个文件夹啊,实际上大家看到了我将它放在了drawable-hdpi中了,实际上drawable-hdpi、drawable-ldpi、drawable-mdpi三个文件夹都属于drawable文件夹的哦。该文件它规定了,当标签获得焦点和失去焦点时,标签上显示什么图片。

例如本例中,就是当state_selected="true"(当标签被选中时),显示@drawable/grey指定的资源图片。当未被选中时,显示@drawable/black指定的资源图片。

tagView.java代码:

[java] view plain copy
  1. packagecn.com.tagview;
  2. importandroid.app.TabActivity;
  3. importandroid.content.Intent;
  4. importandroid.content.res.Resources;
  5. importandroid.os.Bundle;
  6. importandroid.widget.TabHost;
  7. /**
  8. *@authorchenzheng_Java
  9. *@description注意,该类一定要继承TabActivity
  10. */
  11. publicclassTagViewextendsTabActivity{
  12. @Override
  13. publicvoidonCreate(BundlesavedInstanceState){
  14. super.onCreate(savedInstanceState);
  15. //setContentView(R.layout.main);
  16. //android代码中访问application资源的一个类
  17. Resourcesresources=getResources();
  18. //获取当前activity的标签,该方法的实现中已经执行了setContentView(com.android.internal.R.layout.tab_content);
  19. TabHosttabHost=getTabHost();
  20. //每一个标签项
  21. TabHost.TabSpecspec;
  22. //声明一个意图,该意图告诉我们,下一个跳转到的activity是ArtistActivity。
  23. Intentintent=newIntent(this,ArtistActivity.class);
  24. /**
  25. *tabHost.newTabSpec("artist")创建一个标签项,其中artist为它的标签标识符,相当于jsp页面标签的name属性
  26. *setIndicator("艺术标签",resources.getDrawable(R.drawable.ic_tab))设置标签显示文本以及标签上的图标(该图标并不是一个图片,而是一个xml文件哦)
  27. *setContent(intent)为当前标签指定一个意图
  28. *tabHost.addTab(spec);将标签项添加到标签中
  29. */
  30. spec=tabHost.newTabSpec("artist").setIndicator("艺术标签",
  31. resources.getDrawable(R.drawable.ic_tab)).setContent(intent);
  32. tabHost.addTab(spec);
  33. Intentintent2=newIntent(this,MusicActivity.class);
  34. spec=tabHost.newTabSpec("music").setIndicator("音乐标签",
  35. resources.getDrawable(R.drawable.ic_tab)).setContent(intent2);
  36. tabHost.addTab(spec);
  37. Intentintent3=newIntent(this,SportActivity.class);
  38. spec=tabHost.newTabSpec("sport").setIndicator("体育标签",
  39. resources.getDrawable(R.drawable.ic_tab)).setContent(intent3);
  40. tabHost.addTab(spec);
  41. //tabHost.setCurrentTabByTag("music");设置第一次打开时默认显示的标签,该参数与tabHost.newTabSpec("music")的参数相同
  42. tabHost.setCurrentTab(1);//设置第一次打开时默认显示的标签,参数代表其添加到标签中的顺序,位置是从0开始的哦。
  43. }
  44. }

AndroidManifest.xml

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package="cn.com.tagview"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <uses-sdkandroid:minSdkVersion="8"/>
  7. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  8. <!--android:theme="@android:style/Theme.NoTitleBar"的意思是将系统默认的tag标签去掉,为咱们自己的标签空出位置-->
  9. <activityandroid:name=".TagView"
  10. android:label="@string/app_name"
  11. android:theme="@android:style/Theme.NoTitleBar"
  12. >
  13. <intent-filter>
  14. <actionandroid:name="android.intent.action.MAIN"/>
  15. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  16. </intent-filter>
  17. </activity>
  18. <!--在主配置文件中声明用于标签切换的3个activity,记住此处一定要声明,否则会出错
  19. android:name="ArtistActivity"里面ArtistActivity前面是否有.都可以,你只需要保证该类是在manifest标签下package属性的包中即可。
  20. -->
  21. <activityandroid:name="ArtistActivity"android:label="@string/app_name"></activity>
  22. <activityandroid:name="MusicActivity"android:label="@string/app_name"></activity>
  23. <activityandroid:name="SportActivity"android:label="@string/app_name"></activity>
  24. </application>
  25. </manifest>

一切都弄好之后,运行,就出现了最终效果。这里要注意,main.xml是一直都没有用到的哦。

废话连篇:

其实,利用TabHost布局与ListView有很多相似之处,系统也同样为他们提供了帮助类,TabHost-TabActivity ListView-ListActivity .当我们的activity集成了这些类之后,一般在里面我们只需要整理绑定下数据就可以。

再次声明一下,代码中是存在setContentView方法的调用的,只不过因为我们集成了TabActivity,TabActivity的getTabHost方法中已经进行了实现而已。对用户隐藏了,并不代表没有。

项目中为了简单易懂,我们只是在每个标签的内容部分添加了一个文本。实际上,我们完全可以在里面添加图片、视频等等。只要在相应的activity中实现就行了。我们可以看到,这种方式其实有很好的分层结构,activity与activity之间没有太多耦合。

可能一直到现在,有些朋友对TabActivity和ListActivity这种实现都特别的别扭。我这里就简单的说一下,实际上这其实是一种设计模式,模板模式。系统给你提供了一个实现了大部分内容的模板,然后你通过继承模板,去做修改(例如模板中有一个方法没有任何实现,你重写该方法并对其进行具体实现),让其符合你的要求。这就是模板模式的原理。

三、 继承TabActivity并以布局文件进行布局


android tabHost布局 大全_第6张图片

上面的是最终效果图。

代码结构如下。

android tabHost布局 大全_第7张图片

main.xml代码:

[xhtml] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!--该布局文件定义了标签的内容部分,该布局文件一定要以FrameLayout为根元素-->
  3. <FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"android:layout_height="fill_parent">
  5. <!--第一个标签内容-->
  6. <LinearLayoutandroid:id="@+id/widget_layout_Blue"
  7. android:layout_width="fill_parent"android:layout_height="fill_parent"
  8. android:orientation="vertical">
  9. <EditTextandroid:id="@+id/widget34"android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"android:text="EditText"
  11. android:textSize="18sp">
  12. </EditText>
  13. <Buttonandroid:id="@+id/widget30"android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"android:text="Button">
  15. </Button>
  16. </LinearLayout>
  17. <!--第二个标签内容AnalogClock为钟表组件-->
  18. <LinearLayoutandroid:id="@+id/widget_layout_red"
  19. android:layout_width="fill_parent"android:layout_height="fill_parent"
  20. android:orientation="vertical">
  21. <AnalogClockandroid:id="@+id/widget36"
  22. android:layout_width="wrap_content"android:layout_height="wrap_content">
  23. </AnalogClock>
  24. </LinearLayout>
  25. <!--第三个标签内容RadioButton必须在RadioGroup中哦-->
  26. <LinearLayoutandroid:id="@+id/widget_layout_green"
  27. android:layout_width="fill_parent"android:layout_height="fill_parent"
  28. android:orientation="vertical">
  29. <RadioGroupandroid:id="@+id/widget43"
  30. android:layout_width="166px"android:layout_height="98px"
  31. android:orientation="vertical">
  32. <RadioButtonandroid:id="@+id/widget44"
  33. android:layout_width="wrap_content"android:layout_height="wrap_content"
  34. android:text="RadioButton">
  35. </RadioButton>
  36. <RadioButtonandroid:id="@+id/widget45"
  37. android:layout_width="wrap_content"android:layout_height="wrap_content"
  38. android:text="RadioButton">
  39. </RadioButton>
  40. </RadioGroup>
  41. </LinearLayout>
  42. </FrameLayout>

TagHostTest.java的代码:

[java] view plain copy
  1. packagecn.com.tagHost.test;
  2. importandroid.app.TabActivity;
  3. importandroid.graphics.Color;
  4. importandroid.os.Bundle;
  5. importandroid.view.LayoutInflater;
  6. importandroid.view.ViewGroup;
  7. importandroid.widget.TabHost;
  8. publicclassTagHostTestextendsTabActivity{
  9. privateTabHostmyTabhost;
  10. @Override
  11. protectedvoidonCreate(BundlesavedInstanceState){
  12. super.onCreate(savedInstanceState);
  13. myTabhost=this.getTabHost();
  14. /**
  15. *inflate(intresource,ViewGrouproot,booleanattachToRoot)
  16. *resource很显然是一个资源索引id
  17. *当attachToRoot为true时,root代表一个可放置于容器中的组件
  18. *当attachToRoot为false时,root仅代表一个存储值的对象
  19. *该方法的意思是,将根据R.layout.main生成的标签View,添加到由myTabhost.getTabContentView()获得的父容器中
  20. *LayoutInflater类的inflate方法中有如下片段
  21. *if(root!=null&&attachToRoot){
  22. root.addView(temp,params);
  23. }
  24. 其中temp是根据resource指定的资源生成的一个和标签有关的view
  25. */
  26. LayoutInflater.from(this).inflate(R.layout.main,
  27. myTabhost.getTabContentView(),true);
  28. myTabhost.setBackgroundColor(Color.argb(150,22,70,150));
  29. myTabhost.addTab(myTabhost.newTabSpec("One")
  30. .setIndicator("A").setContent(R.id.widget_layout_Blue));
  31. myTabhost.addTab(myTabhost.newTabSpec("Two")
  32. .setIndicator("B",getResources().getDrawable(R.drawable.icon))
  33. .setContent(R.id.widget_layout_green));
  34. myTabhost.addTab(myTabhost.newTabSpec("Three")
  35. .setIndicator("C",getResources().getDrawable(R.drawable.icon))
  36. .setContent(R.id.widget_layout_red));
  37. }
  38. }

这种方法实现起来比较简单,看看我们都做了些什么。

第一步:定义标签内容部分的布局文件,该布局文件必须以FrameLayout为根节点。

第二步:让activity继承TabActivity,然后实现自己的代码。


更多相关文章

  1. Android 在弹出Dialog(带EditText)的同时弹出软键盘并且EditText中
  2. android读取短信内容 自动填充验证码
  3. Android 建立文件夹、生成文件并写入文本文件内容
  4. Android Studio新建布局XML, preview不显示问题解决
  5. Android Studio:在xml布局中不能自动补全代码
  6. Android中时间标签起点
  7. Android纯代码写布局
  8. Android 获取系统短信内容
  9. 【Android 性能优化】布局渲染优化 ( GPU 过度绘制优化总结 | CP

随机推荐

  1. 申请Android Map 的API Key(v2)的最新申
  2. portrait表示横向,landscape表示纵向
  3. Android动态污点分析工具TaintDroid部署
  4. android 中文 api (87) —— BaseInputConn
  5. Android中文API(116)――TableLayout
  6. android app崩溃日志收集以及上传
  7. context对于android的重要意义
  8. android以及ios平台的开发工具设想
  9. Android检测版本更新
  10. android.util.XML介绍