我正在使用 Xamarin.Android 和 MvvmCross 编写一个应用程序,但这个问题通常适用于 native Android。我希望能够声明一个根 fragment ,以便稍后可以将其顶部的所有 fragment 弹出到堆栈中。例如,如果我有 fragment :
A|B|C|D
我目前在 fragment D 上,我希望能够立即弹出 fragment B、C 和 D 以返回到 fragment A。我正在尝试使用 CurrentFragmentManager.PopBackStack
方法在我的 View 演示者中,但它没有按我预期的方式工作。这是我的实现:
public class ViewPresenter : MvxAppCompatViewPresenter
{
private int _rootFragmentId;
private int _currentFragmentId;
public ViewPresenter(IEnumerable<Assembly> androidViewAssemblies) : base(androidViewAssemblies)
{
AddPresentationHintHandler<SetRootHint>(SetRootHintHandler);
AddPresentationHintHandler<PopToRootHint>(PopToRootHintHandler);
}
protected override void ShowFragment(Type view, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
{
base.ShowFragment(view, attribute, request);
// Keep track of the ID of the current fragment (the ID that is given in the Resource)
_currentFragmentId = attribute.FragmentContentId;
}
private bool SetRootHintHandler(SetRootHint hint)
{
_rootFragmentId = _currentFragmentId;
return true;
}
private bool PopToRootHintHandler(PopToRootHint hint)
{
// This doesn't do anything
CurrentFragmentManager.PopBackStack(_rootFragmentId, 0);
return true;
}
}
编辑
Subrato M. 的想法对我有用。这是我为 Xamarin 开发人员提供的 C# 实现:
public class ViewPresenter : MvxAppCompatViewPresenter
{
private string _rootFragmentName;
private string _currentFragmentName;
public ViewPresenter(IEnumerable<Assembly> androidViewAssemblies) : base(androidViewAssemblies)
{
AddPresentationHintHandler<SetRootHint>(SetRootHintHandler);
AddPresentationHintHandler<PopToRootHint>(PopToRootHintHandler);
}
protected override void ShowFragment(Type view, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
{
base.ShowFragment(view, attribute, request);
_currentFragmentName = view.FullName;
}
private bool SetRootHintHandler(SetRootHint hint)
{
_rootFragmentName = _currentFragmentName;
return true;
}
private bool PopToRootHintHandler(PopToRootHint hint)
{
while (CurrentFragmentManager.BackStackEntryCount > 0 &&
CurrentFragmentManager.GetBackStackEntryAt(CurrentFragmentManager.BackStackEntryCount-1).Name.ToLowerInvariant() != _rootFragmentName.ToLowerInvariant())
{
CurrentFragmentManager.PopBackStackImmediate();
}
return true;
}
}
最佳答案
您可以从 BackStackChangedListener 递归调用 popBackStack,直到到达所需的 Fragment:
boolean isBackStackListenerAdded = false;
public void popFragments() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
if(!isBackStackListenerAdded) {
isBackStackListenerAdded = true;
getFragmentManager().addOnBackStackChangedListener(listener);
}
}
}
FragmentManager.OnBackStackChangedListener listener = new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
String fragmentTag = getFragmentManager().getBackStackEntryAt(getFragmentManager().getBackStackEntryCount() - 1).getName();
Fragment currentBackStackFragment = getFragmentManager().findFragmentByTag(fragmentTag);
if(currentBackStackFragment instanceof AFragment) {
if(isBackStackListenerAdded) {
getFragmentManager().removeOnBackStackChangedListener(this);
isBackStackListenerAdded = false;
}
} else {
popFragments();
}
}
};
关于android - 从堆栈中弹出多个 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48117879/