【问题标题】:Fragment Backstack is not restored when orientation changes方向更改时不恢复 Fragment Backstack
【发布时间】:2015-09-17 18:44:30
【问题描述】:

我有一个FragmentActivity,当用户浏览应用程序时,我用用户选择的片段替换当前片段并将事务添加到后台堆栈。一切正常,用户可以通过按返回按钮返回到之前的片段。

当设备方向改变时会出现问题:假设用户看到的第一个片段是 A,然后他导航到 B,然后从 B 导航到 C。 C 内部的内容在横向模式下更好地欣赏,并且 C 有一个特殊的横向布局,因此用户旋转设备。我希望用户以新的方向在 C 中。相反,用户会看到横向的 A。现在他需要再次从 A 导航到 B,然后再导航到 C,才能看到横向的 C。

我希望在方向更改后保留后台堆栈。

如果我在清单中的 Activity 条目上使用 configChange="orientation",则会保留 backstack,但由于未重新创建片段,因此它无法为新方向加载正确的布局。我敢打赌,当这种情况发生时,我可以使用一些讨厌的 hack 来强制重新创建片段,但我认为应该有更好的解决方案来实现如此简单的事情。

显然我做错了什么,因为在this page,有一个解释说

-> Fragment Manager 调用 onSaveInstanceState() 碎片。
-> Activity 和两个 Fragment 都被销毁
-> Activity 的新实例已创建
-> 后堆栈重新创建 片段的新实例

这听起来像我期望的行为,但在我的应用程序中并没有发生。我错过了什么吗?我怎样才能实现这种行为?

我在 SO 上看到了一些类似的问题,但到目前为止,它们都没有帮助我解决这个问题。任何帮助将不胜感激。

【问题讨论】:

  • 您的问题中确实没有足够的信息来回答它。最有可能的是,托管活动总是在片段 A 中创建和交换,无论它是重新开始还是从方向更改中重新创建。我们真的需要一些代码来(dis)确认这一点。其次,configChange="orientation" 不会产生影响,因为'screen size' 也会从纵向变为横向(反之亦然)。从 Android 3.2 开始就是这种情况...
  • 是的,我的意思是将 android:configChanges="orientation|keyboardHidden|screenSize" 添加到清单中,它确实将片段保留在适当的位置,但不会重新创建它们。你想看我活动的哪一部分?为此,我不会覆盖 onSaveInstance 或 onRestoreInstace。

标签: android android-layout android-fragments android-fragmentactivity


【解决方案1】:

我认为您在添加/替换片段之前没有检查 savedInstanceState。试试这个:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Check that the activity is using the layout version
    // with the fragment_container_main FrameLayout
    if (findViewById(R.id.fragment_container_main) != null) {


        // If we're being restored from a previous state,
        // then we don't need to do anything and should return or else
        // we could end up with overlapping fragments.
        if (savedInstanceState != null) { //Do nothing, Android has got your back.

        } else {
            FragmentOne fragmentOne = new FragmentOne();

            // Add the fragment to the fragment_container_main FrameLayout
            getFragmentManager().beginTransaction()
                    .add(R.id.fragment_container_main,
                            fragmentOne,
                            "FRAG_ONE").commit();
        }
    }
}

【讨论】:

  • 不完全是这样,但您的回答帮助我找到了真正的问题。原来导航抽屉片段在方向改变后被重新创建,所以它触发了onNavigationDrawerItemSelected,它总是替换android正在恢复的片段。我通过添加 setRetainInstance(true); 来修复它在我的导航抽屉片段中。
  • 感谢您的提示;)
【解决方案2】:

原来导航抽屉片段在方向改变后被重新创建,所以它触发了onNavigationDrawerItemSelected,它总是替换android正在恢复的片段。我通过添加 setRetainInstance(true); 来修复它在我的导航抽屉片段中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-20
    • 2023-02-21
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多