SupportFragmentManager,popbackstack&屏幕旋转

时间:2016-11-27 21:48:43

标签: android android-fragments

我有一个让我生气的奇怪问题!

情境:

我有Activity A作为启动器ActivityActivity B可以通过Intent中的Activity A启动

Activity A --> Activity B

活动B有一个初始Fragment调用它Fragment C它在Activity B中实例化,如下所示:

if(getSupportFragmentManager().findFragmentByTag(FragmentC.TAG) == null) {
        getSupportFragmentManager()
                 .beginTransaction()
                 .add(R.id.container,
                  FragmentC.newInstance(null), // optional bundle
                  FragmentC.TAG)
                 .commit();
}

Fragment CI中RecyclerView OnClickListener ViewHolderActivity通过Fragment C回复托管FragmentTransaction B此时我开始Activity(在Fragment B中)替换当前的Fragment C,将其称为getSupportFragmentManager() .beginTransaction() .setCustomAnimations( R.anim.fragment_slide_enter, R.anim.fragment_slide_exit, R.anim.fragment_slide_enter_pop, R.anim.fragment_slide_exit_pop) .replace(R.id.container, FragmentD.newInstance(bundle), FragmentD.TAG) .addToBackStack(null) .commit(); D,然后将此事务添加到backstack:

Activity

所以,当我在Fragment D Fragment B与Fragment C到@Override public boolean onSupportNavigateUp() { onBackPressed(); return true; } @Override public void onBackPressed() { super.onBackPressed(); } D的交易时,后面的堆栈处理背压,就像这样:

Actvity

导航正常前进和后退,从开始Activity A到Fragment B - > Fragment D和回来。

问题:

但是,如果我在pop D并旋转屏幕,那么Fragment后台转到Fragment C(撤消交易)我会看到空白Fragment 1}}。更奇怪的是,所有OnCreate() C生命周期方法OnCreateView()OnActivityCreated()add都被调用,并且我有有效的数据/对象(已检查)通过设置断点)。

然而,奇怪的是,如果我从Fragment C开始进行Fragment交易 - > onResume D,显然两者都是一次显示在一起,然后我旋转屏幕并按回去并删除交易没有问题,显然不是解决方案,只是观察。

我已经搜索过了,但我阅读和尝试的所有内容都无效。我之前已经实现了类似的功能,虽然运行良好但我在这里挣扎 - 任何帮助都会受到赞赏。

修改

如果应用程序进入暂停状态(单独留下并且屏幕熄灭)然后再次唤醒,则恢复,片段显示为应该。我private void calculateArea() throws Exception { // Do something } 没有初始化,所以我不知道为什么会这样做。

2 个答案:

答案 0 :(得分:4)

由于屏幕旋转,您的问题出现了。

根据文档:每次设备配置更改时,您的活动都将被销毁并重新创建,例如用户旋转屏幕时。当屏幕改变方向时,系统会破坏并重新创建前台活动,因为屏幕配置已更改,您的活动可能需要加载其他资源(例如布局)

在这种情况下,您的活动B再次启动初始框架C并且所有生命周期方法再次执行

解决方案

  1. 您可以在纵向模式下限制活动。
  2. 您应该在片段中处理onConfigurationChanged()方法并在onCreateView()中定义setRetainInstance(true);
  3. public void setRetainInstance(boolean retain) 控制是否在活动重新创建(例如从配置更改)中保留片段实例。这只能用于不在后栈中的片段。如果设置,则重新创建活动时片段生命周期会略有不同:

     @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
    
            // Checks the orientation of the screen for landscape and portrait
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    
            } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
    
            }
        }
    

答案 1 :(得分:1)

我以前也遇到过同样的问题。我提出了满足我要求的解决方案 在活动B的清单中使用以下代码

 android:configChanges="keyboardHidden|orientation|screenSize"

以上行不允许破坏您的活动,因此您不会遇到片段破坏问题