我正在使用Xamarin.Android和MvvmCross编写应用程序,但这个问题一般适用于原生Android。我希望能够声明一个根片段,以便以后可以在堆栈上弹出它上面的所有片段。例如,如果我有片段:
A | B | C | d
我目前正处于片段D,我希望能够立即弹出片段B,C和D以回到片段A.我试图在我看来使用CurrentFragmentManager.PopBackStack
方法执行此操作主持人,但它没有像我期望的那样工作。这是我的实施:
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;
}
}
答案 0 :(得分:1)
您可以递归地从BackStackChangedListener调用popBackStack,直到找到所需的片段:
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();
}
}
};