Páginas modales de Xamarin.Forms

Download SampleDescargar el ejemplo

Xamarin.Forms es compatible con las páginas modales. Una página modal anima a los usuarios a completar una tarea autocontenida que no se puede abandonar mientras no se complete o se cancele la tarea. En este artículo se muestra cómo navegar a páginas modales.

En este artículo se tratan los temas siguientes:

  • Realizar la navegación: insertar páginas en la pila modal, sacar páginas de la pila modal, deshabilitar el botón Atrás y animar las transiciones de página.
  • Pasar datos al navegar: pasar datos a través de un constructor de página y de un BindingContext.

Información general

Una página modal puede ser cualquiera de los tipos Página compatibles con Xamarin.Forms. Para mostrar una página modal, la aplicación la insertará en la pila modal, donde se convertirá en la página activa, como se muestra en el siguiente diagrama:

Pushing a Page to the Modal Stack

Para volver a la página anterior, la aplicación mostrará la página actual de la pila modal y la nueva página de nivel superior se convertirá en la página activa, tal como se muestra en el siguiente diagrama:

Popping a Page from the Modal Stack

Realizar la navegación

Los métodos de navegación modal se exponen mediante la propiedad Navigation en cualquier tipo Page derivado. Estos métodos proporcionan la capacidad de insertar páginas modales en la pila modal, y sacar páginas modales de la pila modal.

La propiedad Navigation también expone una propiedad ModalStack desde la que se pueden obtener las páginas modales de la pila modal. Pero no existe el concepto de realizar una manipulación de pila modal o extraer la página raíz de la navegación modal. Esto se debe a que estas operaciones no se admiten de forma universal en las plataformas subyacentes.

Nota:

No es necesaria una instancia de NavigationPage para realizar la navegación de páginas modal.

Inserción de páginas en la pila modal

Para navegar a ModalPage, es necesario invocar el método PushModalAsync en la propiedad Navigation de la página actual, como se muestra en el ejemplo de código siguiente:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    ...
    await Navigation.PushModalAsync (detailPage);
  }
}

Esto hace que la instancia de ModalPage se inserte en la pila modal, donde se convertirá en la página activa, siempre que se haya seleccionado un elemento en la ListView en la instancia de MainPage. La instancia de ModalPage se muestra en la siguiente captura de pantalla:

Modal Page Example

Al invocar PushModalAsync, ocurre lo siguiente:

  • La página que llama a PushModalAsync invoca su invalidación OnDisappearing, siempre que la plataforma subyacente no sea Android.
  • Se invoca la invalidación de OnAppearing de la página a la que se ha navegado.
  • La tarea PushAsync finaliza.

Con todo, el orden exacto en el que se producen estos eventos depende de la plataforma. Para obtener más información, consulte el capítulo 24 del libro sobre Xamarin.Forms de Charles Petzold.

Nota:

Las llamadas a OnDisappearing y las invalidaciones de OnAppearing no se pueden tratar como indicaciones garantizadas de navegación de páginas. Por ejemplo, en iOS, la invalidación de OnDisappearing se llama en la página activa cuando la aplicación finaliza.

Sacar páginas de la pila modal

La página activa se puede extraer de la pila modal. Para ello, pulse el botón Atrás del dispositivo, independientemente de si se trata de un botón físico en el dispositivo o de un botón en la pantalla.

Para volver mediante programación a la página original, la instancia ModalPage debe invocar el método PopModalAsync, como se muestra en el ejemplo de código siguiente:

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  await Navigation.PopModalAsync ();
}

Esto hace que la instancia de ModalPage se quite de la pila modal y que la nueva página de nivel superior se convierta en la página activa. Al invocar PopModalAsync, ocurre lo siguiente:

  • Se invoca la invalidación de OnDisappearing de la página que llama a PopModalAsync.
  • Se invoca la invalidación de OnAppearing de la página a la que se vuelve, siempre que la plataforma subyacente no sea Android.
  • La tarea PopModalAsync vuelve.

Con todo, el orden exacto en el que se producen estos eventos depende de la plataforma. Para obtener más información, consulte el capítulo 24 del libro sobre Xamarin.Forms de Charles Petzold.

Deshabilitación del botón Atrás

En Android, el usuario siempre puede volver a la página anterior presionando el botón Atrás estándar en el dispositivo. Si la página modal requiere que el usuario complete una tarea independiente antes de salir de la página, la aplicación debe deshabilitar el botón Atrás. Esto puede realizarse invalidando el método Page.OnBackButtonPressed en la página modal. Para obtener más información, consulte el capítulo 24 del libro sobre Xamarin.Forms de Charles Petzold.

Animación de transiciones de página

La propiedad Navigation de cada página también proporciona métodos de inserción y extracción invalidados que incluyen un parámetro boolean que controla si se debe mostrar una animación de página durante la navegación, como se muestra en el ejemplo de código siguiente:

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PushModalAsync (new DetailPage (), false);
}

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  // Page appearance not animated
  await Navigation.PopModalAsync (false);
}

Al establecer el parámetro boolean en false, la animación de transición de página se deshabilita, mientras que al establecer el parámetro en true, la animación de transición de página se habilita, siempre que la plataforma subyacente lo admita. Sin embargo, los métodos de inserción y extracción que carecen de este parámetro habilitan la animación de manera predeterminada.

Pasar datos al navegar

A veces es necesario que una página pase datos a otra durante la navegación. Dos técnicas para llevar a cabo esto son pasar datos a través de un constructor de página y establecer el BindingContext de la página nueva en los datos. A continuación, se explicarán de uno en uno.

Pasar datos a través de un constructor de página

La técnica más sencilla para pasar datos a otra página durante la navegación es hacerlo a través de un parámetro de constructor de página, que se muestra en el siguiente ejemplo de código:

public App ()
{
  MainPage = new MainPage (DateTime.Now.ToString ("u")));
}

Este código crea una instancia de MainPage y pasa la fecha y la hora actuales en formato ISO8601.

La instancia de MainPage recibe los datos a través de un parámetro de constructor, tal como se muestra en el ejemplo de código siguiente:

public MainPage (string date)
{
  InitializeComponent ();
  dateLabel.Text = date;
}

Después, se establece la propiedad Label.Text para que los datos se muestren en la página.

Pasar datos a través de un objeto BindingContext

Un enfoque alternativo para pasar datos a otra página durante la navegación es establecer el BindingContext de la página nueva en los datos, como se muestra en el siguiente ejemplo de código:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    detailPage.BindingContext = e.SelectedItem as Contact;
    listView.SelectedItem = null;
    await Navigation.PushModalAsync (detailPage);
  }
}

Este código establece el BindingContext de la instancia de DetailPage en la instancia de Contact y después navega a la DetailPage.

Después, la DetailPage utiliza el enlace de datos para mostrar los datos de la instancia de Contact, como se muestra en el ejemplo de código XAML siguiente:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ModalNavigation.DetailPage">
    <ContentPage.Padding>
      <OnPlatform x:TypeArguments="Thickness">
        <On Platform="iOS" Value="0,40,0,0" />
      </OnPlatform>
    </ContentPage.Padding>
    <ContentPage.Content>
        <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
            <StackLayout Orientation="Horizontal">
                <Label Text="Name:" FontSize="Medium" HorizontalOptions="FillAndExpand" />
                <Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" />
            </StackLayout>
              ...
            <Button x:Name="dismissButton" Text="Dismiss" Clicked="OnDismissButtonClicked" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

En el ejemplo de código siguiente se muestra cómo se puede realizar el enlace de datos en C#:

public class DetailPageCS : ContentPage
{
  public DetailPageCS ()
  {
    var nameLabel = new Label {
      FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
      FontAttributes = FontAttributes.Bold
    };
    nameLabel.SetBinding (Label.TextProperty, "Name");
    ...
    var dismissButton = new Button { Text = "Dismiss" };
    dismissButton.Clicked += OnDismissButtonClicked;

    Thickness padding;
    switch (Device.RuntimePlatform)
    {
        case Device.iOS:
            padding = new Thickness(0, 40, 0, 0);
            break;
        default:
            padding = new Thickness();
            break;
    }

    Padding = padding;
    Content = new StackLayout {
      HorizontalOptions = LayoutOptions.Center,
      VerticalOptions = LayoutOptions.Center,
      Children = {
        new StackLayout {
          Orientation = StackOrientation.Horizontal,
          Children = {
            new Label{ Text = "Name:", FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)), HorizontalOptions = LayoutOptions.FillAndExpand },
            nameLabel
          }
        },
        ...
        dismissButton
      }
    };
  }

  async void OnDismissButtonClicked (object sender, EventArgs args)
  {
    await Navigation.PopModalAsync ();
  }
}

Después, una serie de controles Label muestran los datos en la página.

Para más información sobre el enlace de datos, consulte Data Binding Basics (Aspectos básicos del enlace de datos).

Resumen

En este artículo se mostró cómo navegar a páginas modales. Una página modal anima a los usuarios a completar una tarea autocontenida que no se puede abandonar mientras no se complete o se cancele la tarea.