Android OnCreateView 多次调用/使用 ActionBar 和 Fragments

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12201695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:00:23  来源:igfitidea点击:

OnCreateView called multiple times / Working with ActionBar and Fragments

androidandroid-fragmentsandroid-activityandroid-actionbar

提问by Sorin Cioban

I switched part of my App from Activities to Fragments so that I can use the neat ActionBar tabs.

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

However, after completing the transition I ran into an issue: whenever I switch to another tab, that Fragment gets created all over again. Both onCreate and onCreateView get called every time I get to a tab.

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

I have 4 tabs, each of which is meant to open one of these fragments:

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

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

Here's my code for the listener:

这是我的听众代码:

    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) {          

        }

    }

Could someone please point me in the right direction?

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

回答by antonyt

When you call FragmentTransaction.replace(...), Android will effectively perform a sequence of FragmentTransaction.remove(...)(for all Fragments currently added to that container) and FragmentTransaction.add(...)(for your supplied Fragment). Removing a Fragment from the FragmentManagerwill cause the Fragment to be destroyed and its state will no longer be managed. Most noticeably, when you re-add the Fragment all of the views will have been reset. Note: since you are reusing the same Fragment instance, the Fragment will still keep the value any instance variables.

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

One solution to this problem would be to use FragmentTransaction.detach(Fragment)and FragmentTransaction.attach(Fragment)when switching. This will cause the Fragment views to be recreated (onDestroyView()& onCreateView()will be called), but the instance state bundle will be saved and given back to you between calls and so the view state can be maintained. This is the approach taken by FragmentPagerAdapterwhen it tries to switch between Fragments.

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

Alternatively, you could allow the Fragments to be destroyed, but maintain their saved state for them independently. This would use less memory, at the expense of a slower switching time. Methods of note would be FragmentManager.saveFragmentInstanceState(Fragment)and FragmentManager.setInitialSavedState(Fragment.SavedState), in conjuction with adding/removing. This is the approach taken by FragmentStatePagerAdapter.

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

You can have a look at the source for FragmentPagerAdapterand the source for FragmentStatePagerAdapterfor implementation hints.

您可以查看FragmentPagerAdapter来源和 FragmentStatePagerAdapter来源以获得实现提示。

回答by AlikElzin-kilaka

There is the show/hideoption just so the fragments would not need to be repainted/recreated and the onCreate()and onCreateView()won't be reinvoked.

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