2

在我的应用程序中,我具有以下架构:

MainActivity
|_ FirstFragment
|   |_ GridFragment
|   |_ MapFragment
|
|_ SecondFragment
|
|_ ThirdFragment

请注意:

  • MainActivity正在使用ActionBarSherlockSlidingMenu
  • SlidingMenuFirstFragment在片段 ( , SecondFragment, ThirdFragment)之间切换。
  • FirstFragment在操作栏中创建一个按钮以在网格地图模式之间切换。这是,在其亚片段之间切换。

我想要达到的目标

我需要片段在它们之间切换时需要保持其状态。也就是说,如果我在FirstFragment然后选择地图模式(显示MapFragment子片段),然后从幻灯片菜单中选择另一个选项并返回,我应该再次看到地图。现在,当从幻灯片菜单中选择其部分时,它正在重置每个片段。

这并不奇怪,因为目前我在new FirstFragment()按下菜单选项时提交事务。

但是,我首先尝试将每个片段的引用引用到他的父级中。例如,MainActivity有三个片段成员,在提交事务时,检查先前是否存在并在必要时实例化。这一直很好,直到我添加了第二级片段,然后它在提交事务时开始抛出异常(说活动被破坏了)。

您可能已经注意到,我远不是 Android 专家,需要一些关于这个主题的指导。

如何在不为每个片段状态提供参考的情况下保留片段状态?

4

1 回答 1

4

我在发布问题后尝试的下一件事是避免将片段保存在其容器内的局部变量中并FragmentManager.getFragmentByTag()在任何给定时间使用它们来访问它们,但问题仍然存在,就像FragmentTransaction.replace()破坏片段一样。

我的解决方案

正如Luksprog在他的评论中指出的那样,我必须手动管理所有片段。为了实现这一点,我不得不回到我以前的方法,我为每个片段设置了局部变量。然后,MainActivity执行以下操作:

  • 实例化它的三个片段。

    this.firstFragment = new FirstFragment();
    this.secondFragment = new SecondFragment();
    this.thirdFragment = new ThirdFragment();
    
  • 附加三个片段,并隐藏除初始部分之外的所有片段。

    getSupportFragmentManager()
        .beginTransaction()
        .add(R.id.content_frame, this.firstFragment)
        .add(R.id.content_frame, this.secondFragment)
        .add(R.id.content_frame, this.thirdFragment)
        .hide(this.secondFragment)
        .hide(this.thirdFragment)
        .commit();
    
  • 切换内容,SlideMenu就是调用这个函数:

    public void switchContent(Fragment newContent) {
        if (newContent != null) {
            getSupportFragmentManager()
            .beginTransaction()
            .detach(this.firstFragment)
            .detach(this.secondFragment)
            .detach(this.thirdFragment)
            .attach(newContent)
            .commit();
    
            // Restore menu open gesture if map is not present
            if (!(newContent instanceof firstFragment) &&  getSlidingMenu().getTouchModeAbove() != SlidingMenu.TOUCHMODE_FULLSCREEN)
                getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
    
            // Set menu open gesture if map is present
            if (newContent instanceof firstFragment && firstFragment.currentFragment == FirstFragment.MAP_FRAGMENT)
                getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
    
            getSlidingMenu().showContent();
        }
    }
    

然后,具有子片段 ( FirstFragment) 的片段也在做同样的事情,但是:

  • 它使用getChildFragmentManager()而不是getSupportFragmentManager().
  • 它正在使用show()hide()替换内容,因为使用时detach()地图attach()并没有保留它的坐标。
于 2013-05-14T10:34:09.493 回答