简体   繁体   English

Android片段在方向更改时重新创建

[英]Android Fragments recreated on orientation change

I'm developing an app that basically has an ActionBar. 我正在开发一个基本上有ActionBar的应用程序。 When my app starts, the Activity creates the fragments and attaches them to each tab, so when I switch I get different views. 当我的应用程序启动时,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. 因此,我希望能够正常工作的“真实”片段以及使我的应用程序崩溃的“隐藏”Android创建的对应物。 How can I avoid this behavior? 我该如何避免这种行为? I already tried to call setRetainInstance(false) in the SummaryFragment. 我已经尝试在SummaryFragment中调用setRetainInstance(false)。

Thank you 谢谢

You need to check for a savedInstanceState [edit: in your parent activity], and if it exists, don't create your fragments. 您需要检查savedInstanceState [edit:在您的父活动中],如果它存在,请不要创建您的片段。

@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
}

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. 如果没有提供您将片段添加到标签的源代码,我会尽力帮助您改进。

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();
    }

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. 系统在方向更改时自动创建片段,并且如果要在主机活动中跟踪它们,请在主机活动的OnAttachFragment()方法中捕获它们。 And they get the arguments by default, so you can use them to find out which fragment it is. 并且它们默认获取参数,因此您可以使用它们来找出它是哪个片段。

   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;                  
            }
        }
     }
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM