Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从堆栈中弹出多个片段_Android_Android Fragments_Xamarin.android_Mvvmcross - Fatal编程技术网

Android 从堆栈中弹出多个片段

Android 从堆栈中弹出多个片段,android,android-fragments,xamarin.android,mvvmcross,Android,Android Fragments,Xamarin.android,Mvvmcross,我正在用Xamarin.Android和MvvmCross编写一个应用程序,但这个问题通常适用于原生Android。我希望能够声明一个根片段,以便以后可以在堆栈上弹出它上面的所有片段。例如,如果我有片段: A | B | C | D 我目前在片段D上,我希望能够立即弹出片段B、C和D,返回片段A。我正在尝试使用视图演示器中的CurrentFragmentManager.PopBackStack方法来完成此操作,但它并没有像我预期的那样工作。以下是我的实现: public class ViewPr

我正在用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;
    }
}
公共类ViewPresenter:MVXAppCompativeViewPresenter
{
私有int_rootFragmentId;
私有int_currentFragmentId;
公共ViewPresenter(IEnumerable AndroidViewAssembly):基础(AndroidViewAssembly)
{
AddPresentationHintHandler(SetRootHintHandler);
AddPresentationHintHandler(PopToRootHintHandler);
}
受保护的覆盖void ShowFragment(类型视图、MVXFramentPresentationAttribute属性、MvxViewModelRequest请求)
{
ShowFragment(视图、属性、请求);
//跟踪当前片段的ID(资源中给定的ID)
_currentFragmentId=attribute.FragmentContentId;
}
私有布尔SetRootHintHandler(SetRootHint提示)
{
_rootFragmentId=\u currentFragmentId;
返回true;
}
private bool PopToRootHintHandler(PopToRootHint提示)
{
//这没什么用
CurrentFragmentManager.PopBackStack(_rootFragmentId,0);
返回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;
    }
}
公共类ViewPresenter:MVXAppCompativeViewPresenter
{
私有字符串_rootFragmentName;
私有字符串_currentFragmentName;
公共ViewPresenter(IEnumerable AndroidViewAssembly):基础(AndroidViewAssembly)
{
AddPresentationHintHandler(SetRootHintHandler);
AddPresentationHintHandler(PopToRootHintHandler);
}
受保护的覆盖void ShowFragment(类型视图、MVXFramentPresentationAttribute属性、MvxViewModelRequest请求)
{
ShowFragment(视图、属性、请求);
_currentFragmentName=view.FullName;
}
私有布尔SetRootHintHandler(SetRootHint提示)
{
_rootFragmentName=\u currentFragmentName;
返回true;
}
private bool PopToRootHintHandler(PopToRootHint提示)
{
而(CurrentFragmentManager.BackbackEntryCount>0&&
CurrentFragmentManager.GetBackBackbackEntryAt(CurrentFragmentManager.BackBackbackEntryCount-1).Name.ToLowerInvariant()!=\u rootFragmentName.ToLowerInvariant())
{
CurrentFragmentManager.popbackbacksimmediate();
}
返回true;
}
}

您可以从BackbackChangedListener递归调用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();
        }
    }
};

getFragmentManager().findFragmentByTag(“可见片段”)是否返回堆栈顶部的当前活动片段?我刚才编辑了答案。可以在爆炸发生后找到当前的碎片标签。这个想法对我很有用。我编辑了我的帖子,以包含我的C#实现