android TabHost
一个简单的TabHost布局
1.首先继承TabActivity
2.通过TabActivity的getTabHost()方法得到一个TabHost对象
3.定义选项卡的内容(是一个FrameLayout的对象),并与TabHost绑定起来
可以通过一下语句绑定TabHost容器的内容
LayoutInflater.from(this).inflate(R.layout.main, tabHost.getTabContentView(), true);
4.添加选项卡及设置选项的标题及内容
我们知道添加选项卡需要指定一个TabSpec对象,通过TabHost的newTabSpec(选项卡的标识)可以得到,并且可以设定选项卡的标题(可以设置图片),并且设置选项卡内容,如
tabHost.addTab(tabHost.newTabSpec("tab01")
.setIndicator("标签1",getResources().getDrawable(R.drawable.icon))
.setContent(R.id.tab01));
初学者注意了:
如果在 继承了TabActivity的类中设置了,setContentView(R.layout.main),则有可能导致错误,原因可能是因为main布局文件设置不正确(下面有详解),解决办法是建议先删除此行
上面的例子中TabHost只是与一个布局容器绑定,也就是说各个选项卡的内容是写在一个布局文件中的,然后通过不同的id来区分各个选项卡的内容.
如果选项卡的个数过多,或者每个选项卡的布局比较复杂的话,势必会使布局容器显得臃肿而且可读性比较差,不利于后期的维护。
Android中提供了我们还可以通过setContent(Intent intent)来指定每个选项卡的内容
源码: <IGNORE_JS_OP>
有时候我们需要将选项卡的标题设置的更加个性化,虽然我们知道了setIndicator()方法可以设置选项卡的标题的时候可以指定图片,但都是图片在下,文字在图片上方,我们能不能设置成文字在图片下方,或者文字在图片右边呢?
当然可以,android中的setIndicator()方法总共有如下三种形式:
TabHost.TabSpec setIndicator(CharSequence label)
TabHost.TabSpec setIndicator(CharSequence label, Drawable icon)
TabHost.TabSpec setIndicator(View view)
前两种就不说了,想必现在大家都熟悉了。
主要说说第三种,第三种中,方法的参数是一个View,想必大家想在已经知道一些蹊跷了吧. 好的,废话不多说,
直接上源码
源码: <IGNORE_JS_OP>
效果图: <IGNORE_JS_OP> tabtest03.zip (51.65 KB, 下载次数: 3)
Android之TabWidget
上面基本上已经说明了android中TabHost的大部分用法,但还不够。
在开发中,我们有时需要更加实用的TabHost,虽然我们已经可以随心所欲的设置TabHost,但我们一定会发现,在上面的例子中,Label都是在上面,那怎么才能让Label在下面呢?
下面介绍TabWidget
根据SDK文档,
Displays a list of tab labels representing each page in the parent's tab collection. The container object for this widget is TabHost. When the user selects a tab, this object sends a message to the parent container, TabHost, to tell it to switch the displayed page. You typically won't use many methods directly on this object. The container TabHost is used to add labels, add the callback handler, and manage callbacks. You might call this object to iterate the list of tabs, or to tweak the layout of the tab list, but most methods should be called on the containing TabHost object.
我们可以粗略的理解为TabWidget就是Tab的一个集合,也就是Label栏.
根据上面的初学者注意:
不要随便在设置setContentView(R.layout.main)中,这条语句可能引起错误.
如果设置这条语句的话,那么对main布局文件就要正确的配置.
怎么正确定义main.xml布局文件呢?
首先我们需要搞清楚TabHost,TabWidget,FrameLayout之间的关系,
我们知道TabHost好比一个选项卡的容器,包括多个选项卡和选项卡的内容,其中选项卡的内容是一个FrameLayout容器,TabWidget可以理解为选项卡栏.
正确的main.xml文件应该包含这三个组件TabHost,TabWidget,FrameLayout
并且这三个组件的id 必须为
@android:id/tabhost,@android:id/tabs,@android:id/tabcontent
如下,
<?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="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_content"
android:padding="5dp" />
</LinearLayout>
</TabHost>
效果图: <IGNORE_JS_OP>
使用TabWidget选项卡栏在上方源码: <IGNORE_JS_OP> tabtest04.zip (53.09 KB, 下载次数: 1)
如果想要让选项卡栏在下方,那么只需要交换TabWidget和FrameLayout的位置即可,如
<?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="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:padding="5dp" />
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TabWidget>
</LinearLayout>
</TabHost>
效果图: <IGNORE_JS_OP>
使用TabWidget选项卡栏在下方源码: <IGNORE_JS_OP> tabtest05.zip (150.63 KB, 下载次数: 7)
注意了,FrameLayout中多了一行android:layout_weight="1.0"语句
这个属性代表的是比重,android中所有的组件默认这个属性都是为0,意味着他们只在屏幕上显示他们需要空间的大小。
如果设置了该属性,activity将根据设置的值按比例来划分空间的大小
举个例子,如果acitivity中有三个组件,假设屏幕高为90cm,三个组件如果设置了该属性为0的话,那么他们会以正常的方式显示在屏幕上。
如果第一个组件设置组件设置为0,其余两个组件设置为1,那么这个屏幕将会以0:1:1的方式来显示,如果第一个组件默认占10cm,那么其他两个组件各占40cm
另一个例子源码:
TabHost的实现有两种方式,第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost。各个Tab中的内容在布局文件中定义就行了。
mainActivity.xml
1 private TabHost myTabHost; 2 3 @Override 4 public void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 //setContentView(R.layout.main); 7 myTabHost = this.getTabHost(); 8 LayoutInflater.from(this).inflate(R.layout.main, 9 myTabHost.getTabContentView(), true); 10 myTabHost.addTab(myTabHost 11 .newTabSpec("选项卡1") 12 .setIndicator("选项卡1", 13 getResources().getDrawable(R.drawable.img01)) 14 .setContent(R.id.ll01)); 15 myTabHost.addTab(myTabHost 16 .newTabSpec("选项卡2") 17 .setIndicator("选项卡2", 18 getResources().getDrawable(R.drawable.img02)) 19 .setContent(R.id.ll01)); 20 myTabHost.addTab(myTabHost 21 .newTabSpec("选项卡3") 22 .setIndicator("选项卡3", 23 getResources().getDrawable(R.drawable.img03)) 24 .setContent(R.id.ll03)); 25 26 }
Tab内容布局文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="fill_parent" 4 android:layout_height="fill_parent"> 5 <LinearLayout android:id="@+id/ll01" android:layout_width="fill_parent" 6 android:layout_height="fill_parent" android:gravity="center_horizontal" 7 android:orientation="vertical"> 8 <EditText android:id="@+id/widget34" android:layout_width="fill_parent" 9 android:layout_height="wrap_content" android:text="EditText" 10 android:textSize="18sp"> 11 </EditText> 12 <Button android:id="@+id/widget30" android:layout_width="wrap_content" 13 android:layout_height="wrap_content" android:text="Button"> 14 </Button> 15 16 </LinearLayout> 17 <LinearLayout android:id="@+id/ll02" android:layout_width="fill_parent" 18 android:layout_height="fill_parent" android:gravity="center_horizontal" 19 android:orientation="vertical"> 20 <AnalogClock android:id="@+id/widget36" 21 android:layout_width="wrap_content" android:layout_height="wrap_content"> 22 </AnalogClock> 23 </LinearLayout> 24 <LinearLayout android:id="@+id/ll03" android:layout_width="fill_parent" 25 android:layout_height="fill_parent" android:gravity="center_horizontal" 26 android:orientation="vertical"> 27 <RadioGroup android:id="@+id/widget43" 28 android:layout_width="166px" android:layout_height="98px" 29 android:orientation="vertical"> 30 <RadioButton android:id="@+id/widget44" 31 android:layout_width="wrap_content" android:layout_height="wrap_content" 32 android:text="RadioButton"> 33 </RadioButton> 34 <RadioButton android:id="@+id/widget45" 35 android:layout_width="wrap_content" android:layout_height="wrap_content" 36 android:text="RadioButton"> 37 </RadioButton> 38 </RadioGroup> 39 40 </LinearLayout> 41 </FrameLayout>
第二种方式,不继承TabActivity,在布局文件中定义TabHost即可,但是TabWidget的id必须是@android:id/tabs,FrameLayout的id必须是@android:id/tabcontent。
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 android:id="@+id/tabhost" 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content"> 10 <LinearLayout 11 android:orientation="vertical" 12 android:layout_width="fill_parent" 13 android:layout_height="fill_parent"> 14 15 <TabWidget android:id="@android:id/tabs" 16 android:orientation="horizontal" 17 android:layout_width="fill_parent" 18 android:layout_height="wrap_content"> 19 </TabWidget> 20 21 <FrameLayout android:id="@android:id/tabcontent" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content"> 24 <TextView android:id="@+id/view1" 25 android:layout_width="fill_parent" 26 android:layout_height="fill_parent" android:text="Tab1"/> 27 <TextView android:id="@+id/view2" 28 android:layout_width="fill_parent" 29 android:layout_height="fill_parent" android:text="Tab2"/> 30 <TextView android:id="@+id/view3" 31 android:layout_width="fill_parent" 32 android:layout_height="fill_parent" android:text="Tab3"/> 33 </FrameLayout> 34 35 </LinearLayout> 36 </TabHost> 37 </LinearLayout>
mainActivity
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 setContentView(R.layout.main); 5 6 TabHost tabHost = (TabHost) findViewById(R.id.tabhost); 7 tabHost.setup(); 8 TabWidget tabWidget = tabHost.getTabWidget(); 9 10 tabHost.addTab(tabHost 11 .newTabSpec("tab1") 12 .setIndicator("tab1", 13 getResources().getDrawable(R.drawable.img01)) 14 .setContent(R.id.view1)); 15 16 tabHost.addTab(tabHost 17 .newTabSpec("tab2") 18 .setIndicator("tab2", 19 getResources().getDrawable(R.drawable.img02)) 20 .setContent(R.id.view2)); 21 22 tabHost.addTab(tabHost 23 .newTabSpec("tab3") 24 .setIndicator("tab3", 25 getResources().getDrawable(R.drawable.img03)) 26 .setContent(R.id.view3));