在后台获取最新的片段

我怎样才能得到最新的片段实例添加在背后(如果我不知道片段标签&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 ?? 

您可以使用在API级别14中引入的FragmentManager.BackStackEntrygetName()方法。此方法将返回一个标签,该标签是您使用addTobackStack(tag)将片段添加到堆栈时所使用的addTobackStack(tag)

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

你需要确保你像这样将片段添加到了后台:

 fragmentTransaction.addToBackStack(tag); 
 FragmentManager.findFragmentById(fragmentsContainerId) 

函数返回链接到顶层Fragment在后台。 用法示例:

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

我personnaly尝试了许多这些解决scheme,并结束了这个工作解决scheme:

添加这个实用程序的方法,将在以下几次使用,以获得在你的后台碎片的数量:

 protected int getFragmentCount() { return getSupportFragmentManager().getBackStackEntryCount(); } 

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

 getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount())); 

最后,你可以用这个方法在你的后台find你的任何片段:

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

因此,通过调用以下代码可以很容易地获取您的后台堆栈中的顶部碎片:

 protected Fragment getCurrentFragment() { return getFragmentAt(getFragmentCount() - 1); } 

希望这可以帮助!

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

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

由deepak goel给出的答案不适用于我,因为我总是从entry.getName() ;

我所做的是以这种方式将标签设置为片段:

 ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG); 

其中ft是我的分段事务,而FRAGMENT_TAG是标记。 然后我使用这个代码来获取片段:

 Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG); 

保持你自己的背靠背: myBackStack 。 在向FragmentManager Add一个片段时,还要将其添加到myBackStack 。 当onBackStackChanged()myBackStackpopup时,其长度大于getBackStackEntryCount

实际上,没有最新的片段添加到堆栈中,因为您可以在单个事务中向堆栈添加多个或片段,或者只是删除片段而不添加新的片段。

如果你真的想要一堆碎片,并且能够通过堆栈中的索引访问碎片,最好在FragmentManager及其后台上有一个抽象层。 你可以这样做:

 public class FragmentStackManager { private final FragmentManager fragmentManager; private final int containerId; private final List<Fragment> fragments = new ArrayList<>(); public FragmentStackManager(final FragmentManager fragmentManager, final int containerId) { this.fragmentManager = fragmentManager; this.containerId = containerId; } public Parcelable saveState() { final Bundle state = new Bundle(fragments.size()); for (int i = 0, count = fragments.size(); i < count; ++i) { fragmentManager.putFragment(state, Integer.toString(i), fragments.get(i)); } return state; } public void restoreState(final Parcelable state) { if (state instanceof Bundle) { final Bundle bundle = (Bundle) state; int index = 0; while (true) { final Fragment fragment = fragmentManager.getFragment(bundle, Integer.toString(index)); if (fragment == null) { break; } fragments.add(fragment); index += 1; } } } public void replace(final Fragment fragment) { fragmentManager.popBackStackImmediate( null, FragmentManager.POP_BACK_STACK_INCLUSIVE); fragmentManager.beginTransaction() .replace(containerId, fragment) .addToBackStack(null) .commit(); fragmentManager.executePendingTransactions(); fragments.clear(); fragments.add(fragment); } public void push(final Fragment fragment) { fragmentManager .beginTransaction() .replace(containerId, fragment) .addToBackStack(null) .commit(); fragmentManager.executePendingTransactions(); fragments.add(fragment); } public boolean pop() { if (isEmpty()) { return false; } fragmentManager.popBackStackImmediate(); fragments.remove(fragments.size() - 1); return true; } public boolean isEmpty() { return fragments.isEmpty(); } public int size() { return fragments.size(); } public Fragment getFragment(final int index) { return fragments.get(index); } } 

现在不要通过直接调用FragmentManager来添加和删除片段,而应该使用FragmentManager push()replace()pop()方法。 你可以通过调用stack.get(stack.size() - 1)来访问最上面的片段。

但是如果你喜欢黑客,我不得不采取其他方式来做类似的事情。 我必须提到的唯一的事情就是,这些黑客只能使用支持碎片。

第一个黑客就是将所有活动的片段添加到片段pipe理器中。 如果你只是逐个replace片段,并从堆栈中popup,这个方法将返回最上面的片段:

 public class BackStackHelper { public static List<Fragment> getTopFragments( final FragmentManager fragmentManager) { final List<Fragment> fragments = fragmentManager.getFragments(); final List<Fragment> topFragments = new ArrayList<>(); for (final Fragment fragment : fragments) { if (fragment != null && fragment.isResumed()) { topFragments.add(fragment); } } return topFragments; } } 

第二种方法是事件更加黑客,并允许您获取所有添加到最后一个addToBackStack被调用的事务中的片段:

 package android.support.v4.app; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BackStackHelper { public static List<Fragment> getTopFragments( final FragmentManager fragmentManager) { if (fragmentManager.getBackStackEntryCount() == 0) { return Collections.emptyList(); } final List<Fragment> fragments = new ArrayList<>(); final int count = fragmentManager.getBackStackEntryCount(); final BackStackRecord record = (BackStackRecord) fragmentManager.getBackStackEntryAt(count - 1); BackStackRecord.Op op = record.mHead; while (op != null) { switch (op.cmd) { case BackStackRecord.OP_ADD: case BackStackRecord.OP_REPLACE: case BackStackRecord.OP_SHOW: case BackStackRecord.OP_ATTACH: fragments.add(op.fragment); } op = op.next; } return fragments; } } 

请注意,在这种情况下,你必须把这个类放到android.support.v4.app包中。

你可以使用getBackStackEntryAt() 。 为了知道在backstack中可以使用getBackStackEntryCount()

 int lastFragmentCount = getBackStackEntryCount() - 1; 

或者你可以添加一个标签,当添加相应的内容片段,并使用简单的静态string字段(也可以保存在活动实例捆绑在onSaveInstanceState(Bundle)方法)保存最后添加的片段标签,并通过TAG()在任何时候你需要…

最高的(Deepak Goel)答案对我来说效果不好。 不知何故标签没有正确添加。

我最终只是通过stream(使用意图)发送片段的ID,并直接从片段pipe理器中检索它。

这个辅助方法从栈顶获取片段:

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

}

刚刚拿了@roghayeh hosseini(正确)的答案,并在2017年在Kotlin为那些在这里:)

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

*这应该从一个Activity中调用。

请享用 :)