2

我在一个 FragmentActivity 中使用一个 FragmentTabHost,它有 3 个选项卡。如果我从每个选项卡的第一页更改选项卡,它工作正常,但如果我在一个选项卡内导航扔片段然后更改选项卡,它会显示新片段与旧片段重叠。有人可以帮助我吗?

这是 FragmentActivity (fragments_tab.xml) 的布局:

    <?xml version="1.0" encoding="UTF-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/background_gradient">

    <ImageView
        android:contentDescription="@string/app_name"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:src="@drawable/background_gradient" />

    <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">

        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <LinearLayout
            android:id="@+id/realtabcontent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

    </LinearLayout>
    </android.support.v4.app.FragmentTabHost>
    </RelativeLayout>

我的 FragmentActivity 的代码:

    public class MainActivity extends FragmentActivity {

        private FragmentTabHost mTabHost;

        @Override   
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setDB();
            setContentView(R.layout.fragments_tab);

            mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);

            mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);


            mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home",      getResources().getDrawable(R.drawable.ic_menu_home)),
                    HomeFragment.class, null);

            mTabHost.addTab(mTabHost.newTabSpec("Map").setIndicator("Map", getResources().getDrawable(R.drawable.ic_menu_mapmode)),
                    MapMenuFragment.class, null);
            mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.ic_menu_info_details)),
                    InfoFragment.class, null);
        }
}

每个片段都是这样创建的:

public class InfoFragment extends Fragment {

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
    {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_info, container, false);
        return view;
    }

有人可以帮助我吗?

4

5 回答 5

1

我找到了我的问题的解决方案。在我的项目中,每个片段都是扩展类片段的不同类。当 FragmentTabHost 尝试分离旧片段时,它找不到 Fragment 对象,因此它没有删除任何东西。

我不是那么专家,我相信有一种更简单的方法,但是经过许多头痛后,我发现这个解决方案有效。这就是我所做的:

  • 我将每个选项卡的当前片段保存到活动中的 Object 变量中。
  • 我将 FragmentTabHost 的代码复制到自己的类中,并在调用分离或附加时更改了方法 doTabChanged。

(我有 3 个选项卡“主页”、“地图”和“信息”)

分离:

//ft.detach(mLastTab.fragment);
if(mLastTab.tag == "Home") ft.detach((Fragment) tabHomeFragment);
else if(mLastTab.tag == "Info") ft.detach((Fragment) tabInfoFragment);
else ft.detach((Fragment) tabMapFragment);

附:

//ft.attach(newTab.fragment);
if(newTab.tag == "Home") ft.attach((Fragment) tabHomeFragment);
else if(newTab.tag == "Info") ft.attach((Fragment) tabInfoFragment);
else ft.attach((Fragment) tabMapFragment);

tabHomeFragment、tabMapFragment 和 tabInfoFragment 包含每个选项卡的当前片段

于 2013-03-02T10:51:27.983 回答
1

我知道这是一个很老的问题,但无论如何我都会提供我的解决方案,所以它对任何阅读这个问题的人都有用。我有同样的问题,我意识到问题是由调用引起的

mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

因为进行此调用,tabhost 将使用mTabHost.addTab方法中指定的所有片段初始化此 FrameLayout

我解决了我的问题

mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);

这样,FrameLayout R.id.tabcontent 将被隐藏(宽度=0,高度=0),然后,只需实现OnTabChangeListener,您就可以做到这一点

@Override
    public void onTabChanged(String tabId) {
        FragmentTransaction t = getSupportFragmentManager().beginTransaction();
        if (tabId.equals(Frament1.TAG)) {
            t.replace(R.id.realtabcontent, Fragment1.newInstance());
        } else if (tabId.equals(Frament2.TAG)) {
            t.replace(R.id.realtabcontent, Fragment2.newInstance());
        } else if (tabId.equals(Frament3.TAG)) {
            t.replace(R.id.realtabcontent, Fragment3.newInstance());
        }
        //optional
        t.addTobackStack();

        t.commit()
    }

它应该工作

于 2014-10-29T14:08:39.720 回答
1

出现问题是因为 TabHost 无法正确管理您添加的片段。

我曾经遇到过同样的问题,并通过 Fragment Container 模式解决。

FragmentContainer 是从 Fragment 扩展而来的自定义类。您可以使用容器初始化每个选项卡。

每个 Container 通过 getChildFragmentManager() 管理自己的子 Fragment。您可以根据需要添加、替换、删除任何内容。

Tab改变的时候,容器也切换了,没有重叠的问题。

这是我写过的一个简单容器: https ://stackoverflow.com/a/15903349/1695108

于 2013-04-09T13:48:14.623 回答
0

我遇到过类似的情况,以下对我有用。

检查 savedInstanceState 是否不为空,在这种情况下,不要进行片段事务。它将解决这个问题。

if (homeFragment == null) {
    if (savedStateInstance != null) {
    homeFragment = (HomeFragment) fragmentManager.findFragmentByTag(HOME_FRAGMENT);
    return;
}
// tie new fragment
homeFragment = new HomeFragment();
homeFragment.setArguments(bundle);
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(homeFragment, HOME_FRAGMENT);
transaction.commit();
}

希望这可以帮助。

于 2013-10-27T06:52:41.753 回答
0

我实际上有一个类似的问题。我在 ListFragment 中选择项目,然后创建一个新片段并替换选项卡布局中的原始列表片段。我发现当我切换到其他选项卡时,我会遇到多个片段同时显示、相互重叠的问题,或者我会有应该显示的片段消失的问题。我的解决方案是在选择新选项卡时清除后台堆栈,尝试将此代码添加到 TabListener 中的 onTabSelected() 方法

FragmentManager manager = getSupportFragmentManager();

    if(manager.getBackStackEntryCount() > 0)
    {
        manager.popBackStack(null, 
                             FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

这样做为我解决了这个问题。

于 2013-03-01T01:45:08.557 回答