【问题标题】:Best way to switch between two fragments在两个片段之间切换的最佳方式
【发布时间】:2013-09-25 19:08:48
【问题描述】:

我对在两个片段之间切换的单个活动的最佳方式感兴趣。

我可能已经阅读了 15 篇 Stack Overflow 帖子和 5 篇关于如何做到这一点的博客帖子,虽然我认为我拼凑了一个解决方案,但我并不认为它是最好的解决方案。所以,我想听听人们对处理这个问题的正确方法的意见,特别是关于父活动和片段的生命周期。

具体情况如下:

  1. 可以显示两个可能片段之一的父活动。
  2. 这两个片段的状态表明我希望在会话中保持不变,但不一定需要在会话之间保持不变。
  3. 许多其他活动,例如父活动和片段可能被埋在后台堆栈中并由于内存不足而被破坏。
  4. 我希望能够使用后退按钮在片段之间移动(据我了解,我不能使用 setRetainInstance)。

除了一般架构建议之外,我还有以下未解决的问题:

  1. 如果父activity由于内存不足而被销毁,我如何保证两个片段的状态都会被保留,根据这篇文章:When a Fragment is replaced and put in the back stack (or removed) does it stay in memory?。我只需要一个指向父活动中每个片段的指针吗?
  2. 父 Activity 跟踪其当前显示的片段的最佳方式是什么?

提前致谢!

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    我最终使用支持片段管理器添加了两个片段,然后使用分离/附加在它们之间切换。我能够使用 commitAllowingStateLoss(),因为我在其他地方保留了视图的状态,并在 onResume() 中手动设置了正确的片段。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);    
    
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.my_layout, new AFragment(), TAG_A);
        fragmentTransaction.add(R.id.my_layout, new BFragment(), TAG_B);
        fragmentTransaction.commit();
    }
    
    public void onResume() {
        super.onResume();
        if (this.shouldShowA) {
            switchToA();
        } else {
            switchToB();
        }
    }
    
    private void switchToA() {
        AFragment fragA = (AFragment) getSupportFragmentManager().findFragmentByTag(TAG_A);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.detach(getSupportFragmentManager().findFragmentByTag(TAG_B));
        fragmentTransaction.attach(fragA);
        fragmentTransaction.addToBackStack(null);
    
        fragmentTransaction.commitAllowingStateLoss();
        getSupportFragmentManager().executePendingTransactions();
    }
    

    【讨论】:

      【解决方案2】:

      您可能需要考虑在父 Activity 中使用 ViewPager,以便在 Fragment 之间切换。

      这样你就可以浏览它们了。

      如果您想在会话期间保持它们的状态,即使父活动被破坏,您需要将它们设为Parcelable,这样即使当时没有实例化类,您也可以保存状态。如果您旋转设备并希望将当前情况/数据保留在屏幕上,您也需要这样做。

      您应该在他们的onPause 方法中将它们写入Parcelable,然后在onResume 方法中重新创建它们。这样,它们是否因设备方向的变化而被破坏或必须重新创建都没有关系。

      如果您希望能够使用后退按钮在这些片段之间切换,您可以捕获 onBackPressed 的 buttonClick 并进行相应处理。

      如果您需要弄清楚您在给定时间显示的 Fragment,您可以询问您的 ViewPager 他当时正在显示什么 Fragment,这样您就不必跟踪,您可以问知道的人,如果你需要知道的话。

      【讨论】:

      • 感谢您的回复。我不认为我可以在这里使用视图寻呼机,因为视图不应该在视图之间滑动。不过,我肯定会实施 parcelable。我在哪里实现 onBackPressed?
      • OnBackPressed 是一个活动的方法。所以你必须在那里覆盖它。
      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多