关于FragmentTabHost中TabWidget不能移到屏幕下面的Bug

谷歌官方在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。

解决办法就是:

  1. 把那个FramgentTabHost.java文件复制到自己的工程下面
  2. 手动地把155行到177行注释掉(这样就会读取自己设置的布局了)
  3. 将所有引用到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.
 */


你可能感兴趣的:(android,Fragment,布局,tabwidget,FragmentTabHost)