Xamarin MvvmCross Android如何防止返回按钮返回到上一个视图?

8
我正在尝试为以下情况创建一个简洁的解决方案:
我已经构建了一个应用程序,需要凭据来验证用户。每当API想要重新验证用户时,我希望强制用户返回到登录视图。这个功能非常好用,但是当用户在设备上按下后退按钮时,之前的视图会被显示。我希望当用户按下后退按钮时,应用程序退出。
MvvmCross有使用MvxPresentationHint的选项。我创建了一个CustomAndroidViewPresenter,并创建了以下MvxAndroidSetup:
public class Setup : MvxAndroidSetup
{
    private CustomAndroidViewPresenter _presenter;
    public Setup(Context applicationContext)
        : base(applicationContext)
    {
        _presenter = new CustomAndroidViewPresenter(applicationContext);
    }

    protected override IMvxAndroidViewPresenter CreateViewPresenter()
    {
        Mvx.RegisterSingleton(_presenter);
        return _presenter;
    }
}

我知道你应该在活动上调用Finish(); 以防止后退按钮导航回未经身份验证的视图。但是将applicationContext转换为会抛出异常。

public CustomAndroidViewPresenter(Context context)
{
    _context = context;
}

public override void ChangePresentation(MvxPresentationHint hint)
{
    if (hint is LoginOnlyBackStackHint)
    {
        var context = Application.Context;
        if (context is Activity)
        {
            // Context is NOT activity
        }
        try
        {
            Activity x = (Activity) context;
            x.Finish();
            // Exception is thrown
        }
        catch (Exception ex)
        {

        }
    }
    base.ChangePresentation(hint);
}

有人有实现这个的想法吗?

非常感谢。

2个回答

14

我遇到了同样的问题。只需实现一个自定义 Presenter,如果您想要实现这个功能,请设置一些意图标志:

public class CustomAndroidPresenter : MvxAndroidViewPresenter 
    {
        public override void Show(MvxViewModelRequest request)
        {
            if (request != null && request.PresentationValues != null)
            {
                if (request.PresentationValues.ContainsKey("MyCustomFlag"))
                {
                    // Get intent from request and set flags to clear backstack.
                    var intent = base.CreateIntentForRequest(request);
                    intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);

                    base.Show(intent);
                    return;
                }
            }

            base.Show(request);
        }
    }

然后您需要在设置类中设置此演示文稿:

protected override IMvxAndroidViewPresenter CreateViewPresenter()
        {
            var presenter = new CustomAndroidPresenter();
            Mvx.RegisterSingleton<IMvxViewPresenter>(presenter);
            return presenter;
        }

然后要展示一个视图模型(例如您的登录视图),只需设置自定义标志键代码,以便Presenter知道他应该设置intent标志:

然后展示一个视图模型(如你的登录视图), 只需设置自定义flag-key-code, Presenter就会知道他需要设置intent-flags:

protected void ShowViewModel<TViewModel>(bool clearbackstack) where TViewModel : MvxViewModel
        {
            if (clearbackstack)
            {
                var presentationBundle = new MvxBundle(new Dictionary<string, string> { { "MyCustomFlag", "" } });
                ShowViewModel<TViewModel>(presentationBundle: presentationBundle);
                return;
            }

        // Normal start
        ShowViewModel<TViewModel>();
    }

要显示ViewModel(无需后退导航),只需使用以下代码:

ShowViewModel<MyViewModel>(true);

接着,当您按下后退按钮时,无法导航回之前的活动,因为返回堆栈已被清除。


谢谢您的回复!我会研究一下并提供反馈。 - JonHendrix

3
您可以利用OnStop活动生命周期方法。
public class LoginActivity : MvxAppCompatActivity<LoginViewModel>
{   
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.activity_login);
    }

    /// <summary>
    /// Removes activity from history after navigating to new activity.
    /// </summary>
    protected override void OnStop()
    {
        base.OnStop();
        Finish();
    }

    /// <summary>
    /// Closes app if back button is pressed.
    /// </summary>
    public override void OnBackPressed()
    {
        if (FragmentManager.BackStackEntryCount > 0)
        {
            FragmentManager.PopBackStack();
        }
        else
        {
            base.OnBackPressed();
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接