问题描述
我将我的应用程序的一部分从活动切换到片段,以便我可以使用整洁的 ActionBar 选项卡.
I switched part of my App from Activities to Fragments so that I can use the neat ActionBar tabs.
但是,在完成转换后,我遇到了一个问题:每当我切换到另一个选项卡时,该 Fragment 都会重新创建.每次进入选项卡时,onCreate 和 onCreateView 都会被调用.
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.
我有 4 个选项卡,每个选项卡都用于打开以下片段之一:
I have 4 tabs, each of which is meant to open one of these fragments:
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) {
}
}
有人能指出我正确的方向吗?
Could someone please point me in the right direction?
推荐答案
当你调用 FragmentTransaction.replace(...),Android 将有效地执行一系列 FragmentTransaction.remove(...)(针对当前添加到该容器的所有 Fragment)和 FragmentTransaction.add(...)(对于您提供的片段).从 FragmentManager
中移除 Fragment 将导致 Fragment 被销毁,并且不再管理其状态.最值得注意的是,当您重新添加 Fragment 时,所有视图都将被重置.注意:由于您正在重用相同的 Fragment 实例,因此 Fragment 仍会保留任何实例变量的值.
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 FragmentManager
will 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.detach(Fragment) 和 FragmentTransaction.attach(Fragment) 切换时.这将导致重新创建 Fragment 视图(onDestroyView()
& onCreateView()
将被调用),但实例状态包将被保存并返回给您在调用之间,因此可以维护视图状态.这是 FragmentPagerAdapter 在尝试在 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 FragmentPagerAdapter when it tries to switch between Fragments.
或者,您可以允许 Fragment 被销毁,但独立地为它们保持保存的状态.这将使用更少的内存,代价是切换时间变慢.注意方法是 FragmentManager.saveFragmentInstanceState(Fragment) 和 FragmentManager.setInitialSavedState(Fragment.SavedState),结合添加/删除.这是 FragmentStatePagerAdapter 所采用的方法.
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.
你可以看看FragmentPagerAdapter 来源 和 FragmentStatePagerAdapter 的来源 以获取实施提示.
You can have a look at the source for FragmentPagerAdapter and the source for FragmentStatePagerAdapter for implementation hints.
这篇关于OnCreateView 多次调用/使用 ActionBar 和 Fragments的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!