Xamarin MvvmCross Android предотвращает возврат кнопки Назад к предыдущему представлению

Я пытаюсь создать аккуратное решение для следующей ситуации:

Я создал приложение, которое требует учетных данных для аутентификации пользователя. Всякий раз, когда 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(); на действие, чтобы предотвратить backbutton для перехода обратно к неавторизованному представлению. Но приведение 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 ответов


у меня была та же проблема. Просто реализуйте пользовательский презентатор, который устанавливает некоторые флаги намерения, если вы хотите достичь этого:

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

а затем, чтобы показать viewmodel (например, Ваш логин-вид), просто установите свой пользовательский флаг-ключ-код, который ведущий знает, что он должен установить флаги inten:

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

а затем, когда вы нажимаете кнопку назад, вы не можете вернуться к предыдущему действию, потому что backstack очищен.


вы можете воспользоваться методом жизненного цикла активности 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();
        }
    }
}