c# - standard - Xamarin MvvmCross Android Prevent Back Button regresa a la vista anterior
mvvmcross xamarin forms (2)
Intento crear una solución ordenada para la siguiente situación:
Construí una aplicación que requiere credenciales para autenticar al usuario. Cada vez que la API quiere volver a autenticar al usuario, me gustaría forzar al usuario a volver a la vista de inicio de sesión. Esta funcionalidad funciona muy bien, pero cuando el usuario presiona el botón Atrás en el dispositivo, se muestra la vista anterior. Me gustaría ver que cuando el usuario presione el botón Atrás la aplicación salga.
MvvmCross tiene la opción de usar MvxPresentationHint . Creé un CustomAndroidViewPresenter y creé el siguiente 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;
}
}
Sé que debes llamar a Finish (); en una actividad para evitar que el botón retroceda a la vista no autenticada. Pero lanzando el applicationContext para arrojar una excepción.
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);
}
¿Alguien tiene alguna idea de cómo lograr esto?
Muchas gracias de antemano.
Yo tuve el mismo problema. Simplemente implemente un Presentador personalizado, que establece algunos indicadores de intención, si desea lograr esto:
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);
}
}
Luego necesita configurar este presentador en su clase de configuración:
protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
var presenter = new CustomAndroidPresenter();
Mvx.RegisterSingleton<IMvxViewPresenter>(presenter);
return presenter;
}
Y luego, para mostrar un modelo de vista (como su vista de inicio de sesión), simplemente configure su código de clave de marca personalizada para que el presentador sepa que debe establecer los indicadores intencionales:
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>();
}
Para mostrar un modelo de vista (sin navegación hacia atrás) simplemente use el siguiente código:
ShowViewModel<MyViewModel>(true);
Y luego, cuando presiona el botón Atrás, no puede navegar de regreso a su actividad anterior porque se borró el backstack.
Puede aprovechar el método del ciclo de vida de la actividad 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();
}
}
}