Añadiendo un ActionBar con MvvmCross en Xamarin.Android

De acuerdo a la documentación de Android del ActionBar, para poder añadir un ActionBar a un Activity debes crearla heredando desde ActionBarActivity. Esto nos causa un problema con MvvmCross, ya que existe MvxActivity y MvxFragmentActivity, pero no existe MvxActionBarActivity en las librerías estándar. Con el código adjunto podrás implementarla.

Ojo que siempre puedes crear tu Activity de la forma normal, pero perderás mucha de la funcionalidad de MvvmCross. Es por eso que es importante mantenernos usando el framework.

Primero, debes crear una clase que redirija los mensajes del ActionBarActivity estándar hacia MvvmCross:

public class MvxActionBarEventSourceActivity : ActionBarActivity, IMvxEventSourceActivity
{
protected override void OnCreate(Bundle bundle)
{
CreateWillBeCalled.Raise(this, bundle);
base.OnCreate(bundle);
CreateCalled.Raise(this, bundle);
}

protected override void OnDestroy()
{
DestroyCalled.Raise(this);
base.OnDestroy();
}

protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
NewIntentCalled.Raise(this, intent);
}

protected override void OnResume()
{
base.OnResume();
ResumeCalled.Raise(this);
}

protected override void OnPause()
{
PauseCalled.Raise(this);
base.OnPause();
}

protected override void OnStart()
{
base.OnStart();
StartCalled.Raise(this);
}

protected override void OnRestart()
{
base.OnRestart();
RestartCalled.Raise(this);
}

protected override void OnStop()
{
StopCalled.Raise(this);
base.OnStop();
}

public override void StartActivityForResult(Intent intent, int requestCode)
{
StartActivityForResultCalled.Raise(this, new MvxStartActivityForResultParameters(intent, requestCode));
base.StartActivityForResult(intent, requestCode);
}

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
ActivityResultCalled.Raise(this, new MvxActivityResultParameters(requestCode, resultCode, data));
base.OnActivityResult(requestCode, resultCode, data);
}

protected override void OnSaveInstanceState(Bundle outState)
{
SaveInstanceStateCalled.Raise(this, outState);
base.OnSaveInstanceState(outState);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
DisposeCalled.Raise(this);
}
base.Dispose(disposing);
}

public event EventHandler DisposeCalled;
public event EventHandler<MvxValueEventArgs<Bundle>> CreateWillBeCalled;
public event EventHandler<MvxValueEventArgs<Bundle>> CreateCalled;
public event EventHandler DestroyCalled;
public event EventHandler<MvxValueEventArgs<Intent>> NewIntentCalled;
public event EventHandler ResumeCalled;
public event EventHandler PauseCalled;
public event EventHandler StartCalled;
public event EventHandler RestartCalled;
public event EventHandler StopCalled;
public event EventHandler<MvxValueEventArgs<Bundle>> SaveInstanceStateCalled;
public event EventHandler<MvxValueEventArgs<MvxStartActivityForResultParameters>> StartActivityForResultCalled;
public event EventHandler<MvxValueEventArgs<MvxActivityResultParameters>> ActivityResultCalled;
}

Y luego crear la clase abstract MvxActionBarActivity:

    public abstract class MvxActionBarActivity
        : MvxActionBarEventSourceActivity
            , IMvxAndroidView
    {
        protected MvxActionBarActivity()
        {
            BindingContext = new MvxAndroidBindingContext(this, this);
            this.AddEventListeners();
        }

        public object DataContext
        {
            get { return BindingContext.DataContext; }
            set { BindingContext.DataContext = value; }
        }

        public IMvxViewModel ViewModel
        {
            get { return DataContext as IMvxViewModel; }
            set
            {
                DataContext = value;
                OnViewModelSet();
            }
        }

        public void MvxInternalStartActivityForResult(Intent intent, int requestCode)
        {
            base.StartActivityForResult(intent, requestCode);
        }

        public IMvxBindingContext BindingContext { get; set; }

        public override void SetContentView(int layoutResId)
        {
            var view = this.BindingInflate(layoutResId, null);
            SetContentView(view);
        }

        protected virtual void OnViewModelSet()
        {
        }
    }

Con esto ya podrás crear tu activity que herede desde MvxActionBarActivity, implementar tu ActionBar y disfrutar de los bindings que ofrece MvvmCross.

Agregar un comentario