谷歌官方在3.0以后推荐使用Framgent + TabHost的方式。如果有人像我之前一样,苦苦试验怎么将两者结合,这里我要说的是:不用再试图在TabHost里添加Fragment了!因为根本不能加!!!!什么setContent里面的三个参数都不是和fragment对接的。
因为官方推荐的一个专门的控件叫FragmentTabHost,官方文档在这里:http://developer.android.com/reference/android/support/v4/app/FragmentTabHost.html
但是,如果你想把FragmentTabHost里的TabWidget放到屏幕下面,像这样:
<android.support.v4.app.FragmentTabHost
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="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
对不起,不行!
可以说得再宽泛点,你想在layout布局文件上改变它的任意一点布局,你会发现。。。都是徒劳的。——因为Google源码里面存在bug,bug在于:android.support.v4.app.FragmentTabHost.java源码里有一段(155行到177行)的功能是判断如果用户没有设置关于FragmentTabHost的布局文件,就采用默认布局(即TabWidget在最上面),但是这里这个判断的函数永远都是null,就是说它只会采用默认布局,这里是个Bug。
解决办法就是:
- 把那个FramgentTabHost.java文件复制到自己的工程下面
- 手动地把155行到177行注释掉(这样就会读取自己设置的布局了)
- 将所有引用到android.support.v4.app.FragmentTabHost的地方都改成引用这个复制的文件,包括上面xml布局文件的根标签(我上面给的例子是还没改的)
方法不是我想出来的。。。是找了google了老半天找出来的。。这里给出源地址:
http://stackoverflow.com/questions/14745438/how-do-you-put-fragmenttabhost-on-bottom 这人也是这个问题,然后他给出来最后解决问题的链接:
https://code.google.com/p/android/issues/detail?id=40035
再说点其他的,有人可能注意到:我的xml布局文件下面有2个FrameLayout,一个是引用的@android:id/tabcontent,一个是自己定义的id,Google官方的例子也是这样写得,有人可能和我一样有疑问——为什么要这样写?这里给出答案:
android的tabcontent就是对应着TabHost.TebSpec中的setContent()方法的参数(int ViewId)或者Intent或者TabHost.TabContentFactory,分别对应着view视图、在tab的FrameLayout中启动一个Activity【3.0已废弃】、由TabContentFactory对象产生的View。
而Fragment是3.0之后的版本中加进去的,所以@android:id/tabcontent的标签没有实现这个功能,所以要设置FragmentTabHost里面的fragment,就需要自己定义一个标签,并让上面的@android:id/tabcontent在视图上不可见,于是我们看到它的layout_weight=0。
官方在示例中也备注了,原文如下:
/** This is a helper class that implements a generic mechanism for
* associating fragments with the tabs in a tab host. It relies on a trick.
* Normally a tab host has a simple API for supplying a View or Intent that
* each tab will show.
This is not sufficient for switching between
* fragments
. So instead we make the content part of the tab host 0dp high
* (it is not shown) and the TabManager supplies its own dummy view to show
* as the tab content. It listens to changes in tabs, and takes care of
* switch to the correct fragment shown in a separate content area whenever
* the selected tab changes.
*/