Android Fragments 在方向改变时重新创建
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10634854/
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
Android Fragments recreated on orientation change
提问by Luke47
I'm developing an app that basically has an ActionBar. When my app starts, the Activity creates the fragments and attaches them to each tab, so when I switch I get different views.
我正在开发一个基本上有一个 ActionBar 的应用程序。当我的应用程序启动时,Activity 创建片段并将它们附加到每个选项卡,因此当我切换时,我会得到不同的视图。
The problems arise when I try to rotate the device. After some struggle, I noticed that Android automatically recreates the previously added fragments like this:
当我尝试旋转设备时出现问题。经过一番挣扎,我注意到 Android 会自动重新创建之前添加的片段,如下所示:
SummaryFragment.onCreate(Bundle) line: 79
FragmentManagerImpl.moveToState(Fragment, int, int, int) line: 795
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1032
FragmentManagerImpl.moveToState(int, boolean) line: 1014
FragmentManagerImpl.dispatchCreate() line: 1761
DashboardActivity(Activity).onCreate(Bundle) line: 864
...
and then I recreate the fragments as usual. So I have the "real" fragments that I expect to work correctly and their "hidden" Android-created counterparts that make my app crash. How can I avoid this behavior? I already tried to call setRetainInstance(false) in the SummaryFragment.
然后我像往常一样重新创建片段。所以我有我期望正常工作的“真实”片段,以及它们“隐藏”的 Android 创建的对应物,它们使我的应用程序崩溃。我怎样才能避免这种行为?我已经尝试在 SummaryFragment 中调用 setRetainInstance(false)。
Thank you
谢谢
回答by Barak
You need to check for a savedInstanceState [edit: in your parent activity], and if it exists, don't create your fragments.
你需要检查一个savedInstanceState [编辑:在你的父活动中],如果它存在,不要创建你的片段。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (savedInstanceState == null) {
// Do your oncreate stuff because there is no bundle
}
// Do stuff that needs to be done even if there is a saved instance, or do nothing
}
回答by Orest
If you have the similar ui(no specific layout-land files) for both orientations you can set android:configChanges="keyboardHidden|orientation"
to the activity in your manifest file.
如果您在两个方向都有类似的 ui(没有特定的 layout-land 文件),您可以将其设置 android:configChanges="keyboardHidden|orientation"
为清单文件中的活动。
If don't provide please the source code where you're adding the fragments to tabs, and I'll try to help you with improvements.
如果不提供,请提供您将片段添加到选项卡的源代码,我会尽力帮助您进行改进。
回答by Damian
When you create your activity, check to make sure that it doesn't already exist. If it exists, do nothing...Android will recreate it for you.
创建活动时,请检查以确保它不存在。如果它存在,什么都不做……Android 会为你重新创建它。
private void initFragment() {
FragmentManager fragMgr = getSupportFragmentManager();
if (fragMgr.findFragmentByTag(LEADERBOARD_FRAG_TAG) != null) { return; }
frag = new HdrLeaderboardFragment();
FragmentTransaction ft = fragMgr.beginTransaction();
ft.replace(R.id.leaderboard_fragment_wrapper, frag, LEADERBOARD_FRAG_TAG);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
回答by avil
I am not sure if there is a better solution, but this is what i did in latest program.
我不确定是否有更好的解决方案,但这是我在最新程序中所做的。
When a fragment is created automatically by system on orientation change and if you want to keep track of them in host activity, catch them in host activity's OnAttachFragment()
method. And they get the arguments by default, so you can use them to find out which fragment it is.
当系统在方向更改时自动创建片段时,如果您想在主机活动中跟踪它们,请在主机活动的OnAttachFragment()
方法中捕获它们。它们默认获取参数,因此您可以使用它们来找出它是哪个片段。
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment != null) {
if(fragment.getArguments() != null) {
switch (fragment.getArguments().getString(ARG_PARAM1)) {
case FragmentATag:
if (myFragmentA != fragment) {
myFragmentA = (FragmentA) fragment;
}
break;
case FragmentBTag:
if (myFragmentB != fragment) {
myFragmentB = (FragmentB) fragment;
}
break;
}
}
}
}