【问题标题】:Xamarin MvvmCross Android Prevent Back Button returning to previous ViewXamarin MvvmCross Android 防止返回按钮返回上一个视图
【发布时间】:2015-03-12 08:23:54
【问题描述】:

我正在尝试为以下情况创建一个简洁的解决方案:

我已经构建了一个需要凭据来验证用户身份的应用。每当 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);
}

有人知道如何实现这一目标吗?

非常感谢。

【问题讨论】:

    标签: c# android xamarin mvvmcross


    【解决方案1】:

    我遇到了同样的问题。如果您想实现这一点,只需实现一个自定义 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);
            }
        }
    

    那么你需要在你的设置类中设置这个presenter:

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

    然后要显示一个视图模型(例如您的登录视图),只需设置演示者知道他应该设置 inten-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>();
        }
    

    要显示视图模型(没有返回导航),只需使用以下代码:

    ShowViewModel<MyViewModel>(true);
    

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

    【讨论】:

    • 感谢您的回复!我会调查并给出我的反馈
    【解决方案2】:

    您可以利用 OnStop Activity 生命周期方法。

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

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      相关资源
      最近更新 更多