47

我将我的应用程序的一部分从活动切换到片段,以便我可以使用整洁的 ActionBar 选项卡。

但是,在完成转换后,我遇到了一个问题:每当我切换到另一个选项卡时,都会重新创建该片段。每次进入选项卡时都会调用 onCreate 和 onCreateView 。

我有 4 个选项卡,每个选项卡都用于打开以下片段之一:

Fragment ShopFragment = new WebActivity();
Fragment SearchFragment = new SearchActivity(context);
Fragment StoreFragment = new StoreLocatorActivity(context, this);
Fragment BlogsFragment = new BlogsActivity(context, this);

这是我的听众代码:

    class MyTabsListener implements ActionBar.TabListener {
        public Fragment fragment;

        public MyTabsListener(Fragment fragment) {
            this.fragment = fragment;
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            ft.hide(fragment);
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            ft.replace(R.id.fragment_container, fragment);
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {          

        }

    }

有人可以指出我正确的方向吗?

4

2 回答 2

51

当您调用FragmentTransaction.replace(...)时,Android 将有效地执行一系列FragmentTransaction.remove(...)(对于当前添加到该容器的所有 Fragment)和FragmentTransaction.add(...)(对于您提供的分段)。从 will 中移除 FragmentFragmentManager会导致 Fragment 被销毁并且其状态将不再被管理。最值得注意的是,当您重新添加片段时,所有视图都将被重置。注意:由于您正在重用相同的 Fragment 实例,因此 Fragment 仍将保留任何实例变量的值。

解决此问题的一种方法是在切换时使用FragmentTransaction.detach(Fragment)FragmentTransaction.attach(Fragment)。这将导致 Fragment 视图被重新创建(onDestroyView()&onCreateView()将被调用),但实例状态包将被保存并在调用之间返回给您,因此可以维护视图状态。这是FragmentPagerAdapter在尝试在 Fragment 之间切换时采用的方法。

或者,您可以允许 Fragments 被销毁,但独立维护它们的保存状态。这将使用更少的内存,但代价是切换时间更慢。注意的方法是FragmentManager.saveFragmentInstanceState(Fragment)FragmentManager.setInitialSavedState(Fragment.SavedState),以及添加/删除。这是FragmentStatePagerAdapter采用的方法。

您可以查看FragmentPagerAdapter源代码和 FragmentStatePagerAdapter 的源代码以获取实现提示。

于 2012-09-01T14:08:43.243 回答
11

显示/隐藏选项,这样片段就不需要重新绘制/重新创建,onCreate()并且onCreateView()不会被重新调用。

于 2012-12-25T19:00:26.857 回答