Xamarin.Forms Páginas Modais

Baixar exemplo Baixar o exemplo

Xamarin.Forms fornece suporte para páginas modais. Uma página modal incentiva os usuários a concluir uma tarefa independente da qual não se pode sair via navegação até que essa tarefa seja concluída ou cancelada. Este artigo demonstra como navegar até as páginas modais.

Este artigo discute os seguintes tópicos:

  • Executar a navegação – enviar páginas por push para a pilha modal, remover páginas da pilha modal, desabilitar o botão Voltar e animar transições de página.
  • Passar dados ao navegar – passar dados por meio de um construtor de página e de um BindingContext.

Visão geral

Uma página modal pode ser qualquer um dos tipos de página compatíveis com Xamarin.Forms. Para exibir uma página modal, o aplicativo a enviará por push para a pilha modal, na qual ela se tornará a página ativa, conforme mostrado no diagrama a seguir:

Enviar uma página por push para a pilha modal

Para retornar à página anterior, o aplicativo removerá a página atual da pilha modal e, em seguida, a nova página de nível superior se tornará a página ativa, conforme mostrado no diagrama a seguir:

Estourando uma página da pilha modal

Executando a navegação

Os métodos de navegação modal são expostos pela propriedade Navigation em quaisquer tipos derivados de Page. Esses métodos possibilitam enviar páginas modais por push para a pilha modal e remover páginas modais da pilha modal.

A propriedade Navigation também expõe uma propriedade ModalStack da qual as páginas modais na pilha modal podem ser obtidas. No entanto, não há nenhum conceito de realização de manipulação de pilha modal ou remoção do item mais recente da pilha até a página raiz na navegação modal. Isso ocorre porque não há suporte universal para essas operações pelas plataformas subjacentes.

Observação

Uma instância de NavigationPage não é necessária para executar a navegação de página modal.

Enviando páginas por push para a pilha modal

Para navegar até o ModalPage, é necessário invocar o método PushModalAsync na propriedade Navigation da página atual, conforme demonstrado no exemplo de código a seguir:

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

Isso faz com que a instância de ModalPage seja enviada por push para a pilha modal, na qual ela se torna a página ativa, desde que um item tenha sido selecionado no ListView na instância de MainPage. A instância de ModalPage é mostrada nas capturas de tela a seguir:

Exemplo de página modal

Quando PushModalAsync é invocado, os seguintes eventos ocorrem:

  • A página que chama PushModalAsync tem sua substituição de OnDisappearing invocada, desde que a plataforma subjacente não seja o Android.
  • A página para a qual o usuário está navegando tem sua substituição OnAppearing invocada.
  • A tarefa PushAsync é concluída.

No entanto, a ordem exata em que esses eventos ocorrem depende da plataforma. Para obter mais informações, confira o Capítulo 24 do livro de Xamarin.Forms Charles Petzold.

Observação

Chamadas para as substituições OnDisappearing e OnAppearing não podem ser tratadas como indicações garantidas de navegação de página. Por exemplo, no iOS, a substituição OnDisappearing é chamada na página ativa quando o aplicativo é encerrado.

Removendo páginas da pilha modal

A página ativa pode ser removida como o item mais recente da pilha modal pressionando o botão Voltar no dispositivo, independentemente de este ser um botão físico no dispositivo ou um botão na tela.

Para retornar programaticamente à página original, a instância ModalPage deve invocar o método PopModalAsync, conforme demonstrado no exemplo de código a seguir:

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

Isso faz com que a instância ModalPage seja removida da pilha modal, com a nova página de nível superior tornando-se a página ativa. Quando PopModalAsync é invocado, os seguintes eventos ocorrem:

  • A página que chama PopModalAsync tem sua substituição OnDisappearing invocada.
  • A página para a qual o usuário está voltando tem sua substituição de OnAppearing invocada, desde que a plataforma subjacente não seja o Android.
  • A tarefa PopModalAsync é retornada.

No entanto, a ordem exata em que esses eventos ocorrem depende da plataforma. Para obter mais informações, confira o Capítulo 24 do livro de Xamarin.Forms Charles Petzold.

Desabilitando o botão Voltar

No Android, o usuário sempre pode retornar à página anterior pressionando o botão Voltar padrão no dispositivo. Se a página modal exigir que o usuário conclua uma tarefa independente antes de sair da página, o aplicativo deverá desabilitar o botão Voltar. Isso pode ser feito substituindo o método Page.OnBackButtonPressed na página modal. Para obter mais informações, confira o Capítulo 24 do livro de Xamarin.Forms Charles Petzold.

Animando transições de página

A propriedade Navigation de cada página também fornece métodos de envio por push e remoção substituídos que incluem um parâmetro boolean que controla se deve ser exibida uma animação de página durante a navegação, conforme mostrado no código de exemplo a seguir:

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

Definir o parâmetro boolean como false desabilita a animação de transição de página, enquanto definir o parâmetro como true habilita a animação de transição de página, desde que ela tenha suporte da plataforma subjacente. No entanto, os métodos de envio por push e remoção que não têm esse parâmetro habilitam a animação por padrão.

Transmitindo dados ao navegar

Às vezes, é necessário que uma página transmita dados para outra página durante a navegação. Duas técnicas para fazer isso são transmitir dados por meio de um construtor de página e definir o BindingContext como os dados. Descreveremos cada técnica separadamente.

Transmitindo dados por meio de um construtor de página

A técnica mais simples para transmitir dados para outra página durante a navegação é por meio de um parâmetro de construtor de página, que é mostrado no exemplo de código a seguir:

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

Esse código cria uma instância de MainPage, transmitindo a data e a hora atuais no formato ISO8601.

A instância de MainPage recebe os dados por meio de um parâmetro de construtor, conforme mostrado no exemplo de código a seguir:

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

Em seguida, os dados são exibidos na página definindo a propriedade Label.Text.

Transmitindo dados por meio de um BindingContext

Outra abordagem para transmitir dados para outra página durante a navegação é definir o BindingContext da nova página como os dados, conforme mostrado no exemplo de código a seguir:

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

Esse código define o BindingContext da instância de DetailPage como a instância de Contact e, em seguida, navega para o DetailPage.

O DetailPage, em seguida, usa a associação de dados para exibir os dados da instância de Contact, conforme mostrado no exemplo de código XAML a seguir:

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

O exemplo de código a seguir mostra como a associação de dados pode ser feita em 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 ();
  }
}

Em seguida, os dados são exibidos na página por uma série de controles de Label.

Para obter mais informações sobre vinculação de dados, veja Noções básicas de vinculação de dados.

Resumo

Este artigo demonstrou como navegar até as páginas modais. Uma página modal incentiva os usuários a concluir uma tarefa independente da qual não se pode sair via navegação até que essa tarefa seja concluída ou cancelada.