16

我正在开发一个基本上具有 ActionBar 的应用程序。当我的应用程序启动时,Activity 会创建片段并将它们附加到每个选项卡,因此当我切换时,我会得到不同的视图。

当我尝试旋转设备时出现问题。经过一番挣扎,我注意到 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  
...

然后我像往常一样重新创建片段。因此,我拥有了我希望能够正常工作的“真实”片段,以及它们的“隐藏”Android 创建的片段,这些片段使我的应用程序崩溃。我怎样才能避免这种行为?我已经尝试在 SummaryFragment 中调用 setRetainInstance(false)。

谢谢

4

4 回答 4

42

您需要检查 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
}
于 2012-05-17T12:57:45.880 回答
0

如果两个方向都有类似的 ui(没有特定的布局文件),则可以 android:configChanges="keyboardHidden|orientation"在清单文件中设置活动。

如果不提供您将片段添加到选项卡的源代码,我会尽力帮助您改进。

于 2012-05-17T11:35:12.753 回答
0

创建活动时,请检查以确保它不存在。如果它存在,什么也不做……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();
    }
于 2012-05-17T11:36:33.520 回答
0

我不确定是否有更好的解决方案,但这是我在最新程序中所做的。

当系统在方向更改时自动创建片段时,如果您想在宿主活动中跟踪它们,请在宿主活动的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;                  
            }
        }
     }
   }
于 2016-03-17T04:42:39.357 回答