tabHost的两种实现方式

来源:互联网 发布:mac预览图片快捷键 编辑:程序博客网 时间:2024/03/28 17:30

A.布局文件中添加TabHost

上图为最终效果图

代码结构图

 

main.xml

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns: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.     <TabHost android: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.             <TabWidget android: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.              <FrameLayout android:id="@android:id/tabcontent"  
  24.                   android:layout_width="fill_parent"  
  25.                   android:layout_height="fill_parent">  
  26.                     <TextView android:id="@+id/view1"  
  27.                         android:layout_width="fill_parent"  
  28.                         android:layout_height="fill_parent"/>  
  29.                     <TextView android:id="@+id/view2"  
  30.                         android:layout_width="fill_parent"  
  31.                         android:layout_height="fill_parent"/>  
  32.                     <TextView android:id="@+id/view3"  
  33.                         android:layout_width="fill_parent"  
  34.                         android:layout_height="fill_parent"/>  
  35.              </FrameLayout>  
  36.            
  37.          </LinearLayout>  
  38.     </TabHost>  
  39. </LinearLayout>  

java代码如下

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

运行得到正确的结果。

 

 

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

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

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

 

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

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

main.xml

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns: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.     <TabHost android:id="@+id/tabhost" android:layout_width="fill_parent"  
  7.         android:layout_height="wrap_content">  
  8.         <LinearLayout android:orientation="vertical"  
  9.             android:layout_width="fill_parent" android:layout_height="fill_parent">  
  10.   
  11.             <!-- FrameLayout的id属性必须为 @android:id/tabcontent-->  
  12.             <FrameLayout android:id="@android:id/tabcontent"  
  13.                 android:layout_width="fill_parent" android:layout_height="fill_parent">  
  14.                 <TextView android:id="@+id/view1" android:layout_width="fill_parent"  
  15.                     android:layout_height="fill_parent"   
  16.                     android:text="hello baby!"  
  17.                     />  
  18.                 <TextView android:id="@+id/view2" android:layout_width="fill_parent"  
  19.                     android:layout_height="fill_parent" />  
  20.                 <TextView android:id="@+id/view3" android:layout_width="fill_parent"  
  21.                     android:layout_height="fill_parent" />  
  22.             </FrameLayout>  
  23.             <RelativeLayout android:layout_width="fill_parent"  
  24.                 android:layout_height="fill_parent">  
  25.   
  26.                 <!-- TabWidget的id属性必须为 @android:id/tabs-->  
  27.                 <TabWidget android:id="@android:id/tabs"  
  28.                     android:orientation="horizontal" android:layout_width="fill_parent"  
  29.                     android:layout_height="wrap_content"  
  30.                     android:layout_alignParentBottom="true"  
  31.                     android:paddingBottom="0dp"  
  32.                     >  
  33.                 </TabWidget>  
  34.             </RelativeLayout>  
  35.         </LinearLayout>  
  36.     </TabHost>  
  37. </LinearLayout>  

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

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


B.继承TabActivity

1)设置TabHost内容为intent

果图:

 

 

再看下代码结构:

 

 

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

 

然后直接上代码:

ArtistActivity.java

 

[java] view plaincopy
  1. package cn.com.tagview;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class ArtistActivity extends Activity {  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         TextView textView = new TextView(this);  
  13.         // 该文档将会作为标签的内容进行显示  
  14.         textView.setText("艺术内容");  
  15.         setContentView(textView);  
  16.           
  17.     }  
  18. }  

MusicActivity.java

[java] view plaincopy
  1. package cn.com.tagview;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class MusicActivity extends Activity {  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         TextView textView = new TextView(this);  
  13.         // 该文档将会作为标签的内容进行显示  
  14.         textView.setText("音乐内容");  
  15.         setContentView(textView);  
  16.     }  
  17. }  

SportActivity.java

[java] view plaincopy
  1. package cn.com.tagview;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class SportActivity extends Activity {  
  8.   
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         TextView textView = new TextView(this);  
  13.         // 该文档将会作为标签的内容进行显示  
  14.         textView.setText("运动内容");  
  15.         setContentView(textView);  
  16.           
  17.     }  
  18. }  

 

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

 

 

ic_tab.xml代码

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   >  
  5.   <item android:drawable="@drawable/grey"  
  6.         android:state_selected="true"  
  7.   ></item>  
  8.   <item android:drawable="@drawable/black"  
  9.           
  10.   ></item>  
  11. </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 plaincopy
  1. package cn.com.tagview;  
  2.   
  3. import android.app.TabActivity;  
  4. import android.content.Intent;  
  5. import android.content.res.Resources;  
  6. import android.os.Bundle;  
  7. import android.widget.TabHost;  
  8.   
  9. /** 
  10.  * @author chenzheng_Java 
  11.  * @description 注意,该类一定要继承TabActivity 
  12.  */  
  13. public class TagView extends TabActivity {  
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         // setContentView(R.layout.main);  
  18.         // android代码中访问application资源的一个类  
  19.         Resources resources = getResources();  
  20.         // 获取当前activity的标签,该方法的实现中已经执行了setContentView(com.android.internal.R.layout.tab_content);  
  21.         TabHost tabHost = getTabHost();  
  22.         // 每一个标签项  
  23.         TabHost.TabSpec spec;  
  24.   
  25.         // 声明一个意图,该意图告诉我们,下一个跳转到的activity是ArtistActivity。  
  26.         Intent intent = new Intent(this, ArtistActivity.class);  
  27.         /** 
  28.          * tabHost.newTabSpec("artist")创建一个标签项,其中artist为它的标签标识符,相当于jsp页面标签的name属性 
  29.          * setIndicator("艺术标签",resources.getDrawable(R.drawable.ic_tab))设置标签显示文本以及标签上的图标(该图标并不是一个图片,而是一个xml文件哦) 
  30.          * setContent(intent)为当前标签指定一个意图 
  31.          * tabHost.addTab(spec); 将标签项添加到标签中 
  32.          */  
  33.         spec = tabHost.newTabSpec("artist").setIndicator("艺术标签",  
  34.                 resources.getDrawable(R.drawable.ic_tab)).setContent(intent);  
  35.         tabHost.addTab(spec);  
  36.   
  37.         Intent intent2 = new Intent(this, MusicActivity.class);  
  38.         spec = tabHost.newTabSpec("music").setIndicator("音乐标签",  
  39.                 resources.getDrawable(R.drawable.ic_tab)).setContent(intent2);  
  40.         tabHost.addTab(spec);  
  41.   
  42.         Intent intent3 = new Intent(this, SportActivity.class);  
  43.         spec = tabHost.newTabSpec("sport").setIndicator("体育标签",  
  44.                 resources.getDrawable(R.drawable.ic_tab)).setContent(intent3);  
  45.         tabHost.addTab(spec);  
  46.   
  47.         // tabHost.setCurrentTabByTag("music");设置第一次打开时默认显示的标签,该参数与tabHost.newTabSpec("music")的参数相同  
  48.         tabHost.setCurrentTab(1);//设置第一次打开时默认显示的标签,参数代表其添加到标签中的顺序,位置是从0开始的哦。  
  49.   
  50.     }  
  51. }  

 

AndroidManifest.xml

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

 

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

废话连篇:

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

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

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

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

 

2)设置TabHost内容为view

上面的是最终效果图。

代码结构如下。

 

main.xml代码:

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- 该布局文件定义了标签的内容部分,该布局文件一定要以FrameLayout为根元素 -->  
  3. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:layout_width="fill_parent" android:layout_height="fill_parent">  
  5.     <!-- 第一个标签内容 -->  
  6.     <LinearLayout android:id="@+id/widget_layout_Blue"  
  7.         android:layout_width="fill_parent" android:layout_height="fill_parent"  
  8.         android:orientation="vertical" >  
  9.         <EditText android:id="@+id/widget34" android:layout_width="fill_parent"  
  10.             android:layout_height="wrap_content" android:text="EditText"  
  11.             android:textSize="18sp">  
  12.         </EditText>  
  13.         <Button android:id="@+id/widget30" android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content" android:text="Button">  
  15.         </Button>  
  16.     </LinearLayout>  
  17.     <!-- 第二个标签内容 AnalogClock为钟表组件-->  
  18.     <LinearLayout android:id="@+id/widget_layout_red"  
  19.         android:layout_width="fill_parent" android:layout_height="fill_parent"  
  20.         android:orientation="vertical"  >  
  21.         <AnalogClock android:id="@+id/widget36"  
  22.             android:layout_width="wrap_content" android:layout_height="wrap_content">  
  23.         </AnalogClock>  
  24.     </LinearLayout>  
  25.     <!-- 第三个标签内容 RadioButton必须在RadioGroup中哦 -->  
  26.     <LinearLayout android:id="@+id/widget_layout_green"  
  27.         android:layout_width="fill_parent" android:layout_height="fill_parent"  
  28.         android:orientation="vertical">  
  29.         <RadioGroup android:id="@+id/widget43"  
  30.             android:layout_width="166px" android:layout_height="98px"  
  31.             android:orientation="vertical">  
  32.             <RadioButton android:id="@+id/widget44"  
  33.                 android:layout_width="wrap_content" android:layout_height="wrap_content"  
  34.                 android:text="RadioButton">  
  35.             </RadioButton>  
  36.             <RadioButton android: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 plaincopy
  1. package cn.com.tagHost.test;  
  2.   
  3. import android.app.TabActivity;  
  4. import android.graphics.Color;  
  5. import android.os.Bundle;  
  6. import android.view.LayoutInflater;  
  7. import android.view.ViewGroup;  
  8. import android.widget.TabHost;  
  9.   
  10. public class TagHostTest extends TabActivity {  
  11.   
  12.     private TabHost myTabhost;  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         myTabhost = this.getTabHost();  
  18.   
  19.         /** 
  20.          * inflate(int resource, ViewGroup root, boolean attachToRoot) 
  21.          * resource 很显然是一个资源索引id 
  22.          * 当attachToRoot为true时,root代表一个可放置于容器中的组件 
  23.          * 当attachToRoot为false时,root仅代表一个存储值的对象 
  24.          * 该方法的意思是,将根据R.layout.main生成的标签View,添加到由myTabhost.getTabContentView()获得的父容器中 
  25.          * LayoutInflater类的inflate方法中有如下片段 
  26.          *  if (root != null && attachToRoot) { 
  27.                         root.addView(temp, params); 
  28.                     } 
  29.             其中temp是根据resource指定的资源生成的一个和标签有关的view 
  30.          */  
  31.         LayoutInflater.from(this).inflate(R.layout.main,  
  32.                 myTabhost.getTabContentView(), true);  
  33.         myTabhost.setBackgroundColor(Color.argb(1502270150));  
  34.   
  35.         myTabhost.addTab(myTabhost.newTabSpec("One")  
  36.                 .setIndicator("A").setContent(R.id.widget_layout_Blue));  
  37.   
  38.         myTabhost.addTab(myTabhost.newTabSpec("Two")  
  39.                 .setIndicator("B", getResources().getDrawable(R.drawable.icon))  
  40.                 .setContent(R.id.widget_layout_green));  
  41.   
  42.         myTabhost.addTab(myTabhost.newTabSpec("Three")  
  43.                 .setIndicator("C", getResources().getDrawable(R.drawable.icon))  
  44.                 .setContent(R.id.widget_layout_red));  
  45.     }  
  46. }  

 

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

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

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




0 0
原创粉丝点击