Android的重新排序片段Backstack片段、Android、Backstack

2023-09-06 00:41:15 作者:穿过山和风

我有一些在我的抽屉式导航上市页/片段,用户很可能经常在它们之间进行切换,我想他们在backstack,使他们能够导航回,但我只希望每个片段中的一个实例的backstack使得用户不不必preSS回次疯狂数退出该应用。我无法弄清楚如何有效地重新排序的backstack没有书页得到清除。

I have a number of pages/fragments listed in my navigation drawer, the user is likely to switch between these frequently and I want them in the backstack so that they can navigate back, but I only want one instance of each fragment in the backstack so that the user doesn't not have to press back an insane number of times to exit the app. I can't figure out how to effectively 'reorder' the backstack' without pages getting removed.

目前,当我改变我就是用这个code要更改片段,并确保它只有在后面的堆栈一旦页

Currently when I change page I was using this code to change the fragment and make sure it's only in the back stack once

  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();
  }

我用这个code在onBack pressed

I use this code in onBackPressed

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

这工作,但它意味着它删除的网页,我不想删除。例如:

This works but it means it removes pages I don't want removed. Example:

在我的用户访问6页顺序 A> B> C> D> E> ç,因为我正在做一个删除我期待下面的堆栈:

When my user visits 6 pages in the order A > B > C > D > E > C because I'm doing a remove I expected the following stack:

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

但我真正得到如下 - 它弹出的一切行动,以匹配名称的元素,这是无论我是否包括卸下摆臂((片段)mFragment)或不 - (我'已经已经意识到,现在删除不影响backstack,所以没必要指出这一点的):

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

如果我不使用一个名称,而是使用空增加我得到以下的backstack时:

If I don't use a name and instead use null when adding to the backstack I get the following:

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

我怎样才能得到我预期的行为?是否有可能在所有还是我将需要完全记录更改自己和跳过backstack?

How can I get the behaviour I expect? Is it possible at all or am I going to need to record the changes myself and skip the backstack altogether?

推荐答案

有没有API来做到这一点,但becuse我上周知道同样的事情, 我把它作为一个练习的实现它自己。

There is no API to do this, but becuse I was wondering the same thing last week, I took it as an exercise an implemented it myself.

我的方法,可以删除片段从backstack的任意位置,这是通过使用refrection来修改存储backstack信息FragmentManagerImpl和BackStackRecord.

My method allows you to remove a Fragment from anywhere in the backstack and this is achieved by using refrection to modify the internal variables that store the backstack information in FragmentManagerImpl and BackStackRecord.

有几个重要的变量:

mBackStack - 存储 BackStackRecord S中的片段持有信息,在previous的,动画等 mActive - 所有添加片段取值 mAvailBackStackIndices - 存储可用于新插入记录的指标中,值,即指数在 mActive mBackStack - stores the BackStackRecords that hold the Fragment info, the previous ones, animations, etc mActive - all added Fragments mAvailBackStackIndices - stores the indices that can be used by the newly inserted records, i.e. indices of null values in mActive and other

测试与150 + 片段和无法发现任何泄漏,但只监测了 DDMS 堆并没有执行任何其他内存分析。 所以,因为成才可能被打破,探索code,再测试,看看是否有人提供了一个更好的答案,并重新考虑,如果你真的需要做到这一点在你的项目中。

Tested with 150+ Fragments and couldn't notice any leaks, but only monitored the heap in DDMS and did not perform any other memory analysis. So because someting may be broken, explore the code, re-test it, see if anyone provides a better answer, and rethink if you really need to do this in your project.

我上传了code作为GitHub上一个要点,希望它帮助。

I uploaded the code as a gist on GitHub, hope it helps.