当前位置: 首页 > 知识库问答 >
问题:

Android重新排序片段回退

闻人树
2023-03-14

我的抽屉菜单中列出了许多页面/片段,用户可能会经常在这些页面/片段之间切换,我希望它们在后台堆栈中,以便它们可以导航回来,但我只希望每个片段的一个实例在后台堆栈中,以便用户不必按太多次才能退出应用程序。我不知道如何在不删除页面的情况下有效地“重新排序”后台。

目前,当我更改页面时,我使用这段代码来更改片段,并确保它只在后堆栈中出现一次

  if (mFragMgr == null) {
      mFragMgr = getSupportFragmentManager();
  }

  String backStateName = fragmentDescriptor.name();
  boolean fragmentPopped = mFragMgr.popBackStackImmediate(backStateName, 0);
  if (!fragmentPopped){
      mFragMgr.beginTransaction()
      .remove((Fragment) mFragment)
      .replace(R.id.content_frame, (Fragment) mFragment)
      .addToBackStack(backStateName)
      .commit();
  }

我在onBackPush中使用此代码

  @Override
  public void onBackPressed() {
      if (mFragMgr.getBackStackEntryCount() > 0) {
          mFragMgr.popBackStackImmediate();
      } else {
          super.onBackPressed();
      }
  }

这可以工作,但这意味着它会删除我不想删除的页面。示例:

当我的用户按顺序 A 访问 6 个页面

                            [E]    [C]
                     [D]    [D]    [E]
              [C]    [C]    [C]    [D]
       [B]    [B]    [B]    [B]    [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]

但我实际得到的是以下内容——它会弹出与名称匹配的元素的所有内容,这与我是否包含“”无关。删除((片段)m片段)”-(我现在已经意识到删除不会影响后栈,所以没有必要指出这一点):

                            [E]
                     [D]    [D]
              [C]    [C]    [C]    [C]
       [B]    [B]    [B]    [B]    [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]

如果我在添加backstack时不使用名称,而是使用null,我会得到以下结果:

                                   [C]
                            [E]    [E]   
                     [D]    [D]    [D]    
              [C]    [C]    [C]    [C]   
       [B]    [B]    [B]    [B]    [B]  
[A] -> [A] -> [A] -> [A] -> [A] -> [A] 

我怎样才能得到我期望的行为?这是可能的,还是我需要自己记录更改并完全跳过后栈?


共有2个答案

刘博雅
2023-03-14

当您想在片段之前重用它时,只需首先隐藏所有片段并一次显示所需的片段。通过这样做,您可以重用片段,而无需删除它们,也无需重新加载片段。但在实现它之前,请确保必须将片段添加到backstack。

罗昊空
2023-03-14
匿名用户

没有这样做的API,但是因为我上周也在想同样的事情,< br >我把它当作一个练习,自己实现了它。

我的方法允许您从反栈中的任何位置删除片段,这是通过使用refrection修改在FragmentManagerImpl和BackStackRecord中存储反栈信息的内部变量来实现的。

有几个重要的变量:

  • mBackStack-存储保存片段信息、上一个片段、动画等的backstack记录
  • mActive-所有添加的片段s
  • mavailbackstackindex-存储新插入记录可以使用的索引,即mActive
  • null值的索引
  • 及其他

用150个< code >片段进行了测试,没有发现任何泄漏,但只监视了< code>DDMS中的堆,没有执行任何其他内存分析。< br >因此,因为有些东西可能会被破坏,所以探索代码,重新测试它,看看是否有人提供了更好的答案,并重新考虑您是否真的需要在您的项目中这样做。

我将代码作为要点上传到GitHub上,希望能有所帮助。

 类似资料:
  • 问题内容: 我只是很好奇,因为我已经在FragmentActivity中设置了Fragment选项卡,如何从FragmentActivity或Fragment本身重新加载片段,以清除并重新加载该选项卡。我本质上需要重新选择选项卡以替换片段时发生的相同事情。有一种简单的方法可以执行此操作并重新加载片段吗? 问题答案: 创建一个方法,该方法开始FragmentTransaction,分离片段,然后提交

  • 我在一个详细视图中使用ViewPager和FragmentPagerAdapter。这意味着我有一个项目列表,一个屏幕显示单个项目的细节。但用户可以左右滑动来浏览所有项目。这遵循了谷歌滑动视图的指导方针。 但是我想知道一件事。在ListView中,每一行的视图都会被重用。一旦一行从屏幕上滚动出来,它就会被重用为绑定到ListView的适配器的getView方法的转换器视图参数。但是这种重用行为似乎

  • 我正在尝试使用FragmentStatePagerAdapter和ViewPager制作一个包含4个选项卡的应用程序。 当我第一次运行应用程序时,如果我按顺序(0到3)选择选项卡,一切正常,然后如果我尝试执行返回(3到0)的方式,选项卡1将显示一个空白屏幕,如果,在那之后,我选择选项卡2,然后也是空的,如果我转到选项卡0,然后再次按顺序执行选项卡2返回生活,有时选项卡1返回生活,但我没有找到任何顺

  • 问题内容: 如何在不更改HTML源代码的情况下重新排序div? 例如,我希望div以#div2,#div1,#div3的顺序显示,但是在HTML中它们是: 谢谢! 问题答案: 没有使用css对元素进行重新排序的万能方法。 您可以通过将它们全部向右浮动来水平反转它们的顺序。或者,您可以将它们相对于正文或其他包含元素的绝对位置进行定位- 但这对元素的大小以及相对于页面上其他元素的位置存在严格的限制。

  • 我有一个关于火警分类的问题。

  • 在Android中,当我们用一个新的片段替换容器视图时,我们可以使用replace()和addToBackStack(),因此按下back按钮就可以转到上一个片段。 但如果出现以下情况怎么办: 在Activity1中,我可以按下back按钮从fragment2转到fragment1。但当fragment2启动另一个活动时,从Activity2按下back按钮,它会将我带到Activity1中的fr