在backstack中获取最新的片段

Lee*_*fin 97 android android-fragments back-stack

如何在backstack中添加最新的片段实例(如果我不知道片段标签和id)?

FragmentManager fragManager = activity.getSupportFragmentManager();
FragmentTransaction fragTransacion = fragMgr.beginTransaction();

/****After add , replace fragments 
  (some of the fragments are add to backstack , some are not)***/

//HERE, How can I get the latest added fragment from backstack ??
Run Code Online (Sandbox Code Playgroud)

Dee*_*oel 149

您可以使用API级别14中引入的getName()方法FragmentManager.BackStackEntry.此方法将返回一个标记,该标记是您将Fragment添加到Backstack时使用的标记addTobackStack(tag).

int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1
FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment fragment = getFragmentManager().findFragmentByTag(tag);
Run Code Online (Sandbox Code Playgroud)

您需要确保将片段添加到backstack,如下所示:

fragmentTransaction.addToBackStack(tag);
Run Code Online (Sandbox Code Playgroud)

  • 为了按标签查找片段,必须使用相同的标签添加/替换它.`FragmentTransaction.add(int containerViewId,Fragment fragment,String tag)`或`FragmentTransaction.replace(int containerViewId,Fragment fragment,String tag)`[doc](http://developer.android.com/reference/android/app /FragmentTransaction.html#replace(int,%20android.app.Fragment,%20java.lang.String)) (24认同)
  • 如果我不能通过pop方法访问片段,那么将它称为"堆栈"是什么意思? (13认同)
  • RTFM:http://developer.android.com/reference/android/app/FragmentManager.BackStackEntry.html#getName() (5认同)
  • 返回null (4认同)
  • 这样做的问题是如果后端堆栈中有一个片段两次,当你拥有的是索引或backstackentry实体时,你无法检索特定的片段. (3认同)

ash*_*rov 48

FragmentManager.findFragmentById(fragmentsContainerId) 
Run Code Online (Sandbox Code Playgroud)

function返回Fragmentbackstack中的top链接.用法示例:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", fr.getClass().getSimpleName());
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

  • 这个答案在我的项目中运行良好,因为我将除根片段之外的每个片段添加到后栈.但我想如果最新添加的片段没有添加到Backstack中,这个答案将无效. (2认同)

pti*_*nou 40

我个人尝试了很多这样的解决方案,最终得到了这个有效的解决方案:

添加此实用程序方法,将在下面多次使用以获取backstack中的片段数:

protected int getFragmentCount() {
    return getSupportFragmentManager().getBackStackEntryCount();
}
Run Code Online (Sandbox Code Playgroud)

然后,当您使用FragmentTransaction方法添加/替换片段时,为片段生成唯一标记(例如:通过使用堆栈中的片段数量):

getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount()));
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用此方法在Backstack中找到任何片段:

private Fragment getFragmentAt(int index) {
    return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null;
}
Run Code Online (Sandbox Code Playgroud)

因此,通过调用以下方法可以轻松地获取backstack中的顶部片段:

protected Fragment getCurrentFragment() {
    return getFragmentAt(getFragmentCount() - 1);
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!


rog*_*ini 7

此帮助程序方法从堆栈顶部获取片段:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}
Run Code Online (Sandbox Code Playgroud)


Ere*_*ez 6

fragmentMananger中有一个片段列表.请注意,删除片段不会使列表大小减小(片段条目只是变为null).因此,有效的解决方案是:

public Fragment getTopFragment() {
 List<Fragment> fragentList = fragmentManager.getFragments();
 Fragment top = null;
  for (int i = fragentList.size() -1; i>=0 ; i--) {
   top = (Fragment) fragentList.get(i);
     if (top != null) {
       return top;
     }
   }
 return top;
}
Run Code Online (Sandbox Code Playgroud)

  • 不可靠的。三个原因:1) 这是一个片段管理器知道的所有片段的列表,而不仅仅是堆栈上的片段。2) 不能保证片段管理器会在列表末尾不断添加新的。当然,它会在简单的测试中这样做,但是如果一个片段被删除,留下一个空值,然后在某些情况下片段管理器决定重用那个空槽呢?不是说它会,但不能保证它永远不会,在任何情况下。3) 如果您或一些未来的程序员开始使用附加/分离来管理片段,这将与堆栈不匹配。 (2认同)

Edu*_*rdo 5

Deepak Goel给出的答案对我不起作用,因为我总是从中得到空值entry.getName()

我要做的是通过以下方式将Tag设置为片段:

ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG);
Run Code Online (Sandbox Code Playgroud)

ft是我的片段交易,FRAGMENT_TAG是标签。然后,我使用以下代码来获取片段:

Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG);
Run Code Online (Sandbox Code Playgroud)


Shi*_*e85 5

刚刚接受了@roghayeh hosseini(正确)的答案,并在 Kotlin 中为 2017 年的人提供了答案:)

fun getTopFragment(): Fragment? {
    supportFragmentManager.run {
        return when (backStackEntryCount) {
            0 -> null
            else -> findFragmentByTag(getBackStackEntryAt(backStackEntryCount - 1).name)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

*这应该从活动内部调用。

享受 :)


The*_*ist 5

科特林

activity.supportFragmentManager.fragments.last()
Run Code Online (Sandbox Code Playgroud)

  • 如果“fragments”为空,您可能需要使用“.lastOrNull()”。 (7认同)

Bla*_*elt 3

您可以使用getBackStackEntryAt()。为了了解活动在后台堆栈中保存了多少条目,您可以使用getBackStackEntryCount()

int lastFragmentCount = getBackStackEntryCount() - 1;
Run Code Online (Sandbox Code Playgroud)

  • 但是我怎样才能得到backstack中的最后一个片段呢?popBackStackEntryAt() 仅返回 BackStackEntry 实例,而不返回片段 (14认同)
  • 这个答案是错误的,我看到 backstack 条目的 id 为 0,因此无法通过 id 检索片段。 (3认同)
  • 这已经很旧了,但是对于任何在这里徘徊的人来说:返回堆栈不保存片段,而是保存片段事务,这就是为什么这个答案是错误的 (2认同)