TabbedPage de Xamarin.Forms

Download SampleDescargar el ejemplo

Xamarin.FormsTabbedPage consta de una lista de pestañas y un área de detalles más grande, con cada pestaña cargando contenido en el área de detalles. En las capturas de pantalla siguientes se muestra un elemento TabbedPage en iOS y Android:

Screenshot of a TabbedPage containing three tabs, on iOS and Android

En iOS, la lista de pestañas aparece en la parte inferior de la pantalla y el área de detalles está arriba. Cada pestaña está formada por un título y un icono, que debe ser un archivo PNG con un canal alfa. En orientación vertical, los iconos de la barra de pestañas aparecen encima de los títulos de pestañas. En orientación horizontal, los iconos y los títulos aparecen unos al lado de otros. Además, se puede mostrar una barra de pestañas normal o compacta, dependiendo del dispositivo y la orientación. Si hay más de cinco pestañas, aparece una pestaña Más que puede usarse para acceder a las demás pestañas.

En Android, la lista de pestañas aparece en la parte superior de la pantalla y el área de detalles está debajo. Cada pestaña está formada por un título y un icono, que debe ser un archivo PNG con un canal alfa. Sin embargo, se pueden mover las pestañas a la parte inferior de la pantalla con una plataforma específica. Si hay más de cinco pestañas, y la lista de pestañas está en la parte inferior de la pantalla, aparece una pestaña Más que puede usarse para acceder a las demás pestañas. Para información sobre los requisitos de los iconos, consulte Pestañas en material.io y Compatibilidad con distintas densidades de píxeles en developer.android.com. Para información sobre cómo mover las pestañas a la parte inferior de la pantalla, consulte Establecimiento de la posición y el color de la barra de herramientas de TabbedPage.

En la Plataforma universal de Windows (UWP), la lista de pestañas aparece en la parte superior de la pantalla y el área de detalles se muestra debajo. Cada pestaña está formada por un título. Sin embargo, se pueden agregar iconos a cada pestaña con una plataforma específica. Para más información, consulte Iconos de TabbedPage en Windows.

Sugerencia

Los archivos de Gráficos vectoriales escalables (SVG) se pueden mostrar como iconos de pestaña en un elemento TabbedPage:

  • La clase TabbedRenderer para iOS tiene un método reemplazable GetIcon que se puede usar para cargar iconos de pestaña desde un origen especificado. Además, en caso necesario se pueden proporcionar versiones seleccionadas y sin seleccionar de un icono.
  • La clase TabbedPageRenderer para Android AppCompat tiene un método reemplazable SetTabIconImageSource que se puede usar para cargar iconos de pestaña desde un elemento Drawable personalizado. Como alternativa, los archivos SVG se pueden convertir en recursos Drawable vectoriales, que Xamarin.Forms puede mostrar de forma automática. Para obtener más información sobre cómo convertir archivos SVG en recursos Drawable vectoriales, vea Cómo agregar gráficos vectoriales de varias densidades en developer.android.com.

Para obtener más información, vea TabbedPage de Xamarin.Forms con iconos de pestaña de SVG.

Creación de TabbedPage

Para crear una instancia de TabbedPage se pueden usar dos métodos:

Con ambos métodos, TabbedPage muestra cada página cuando el usuario selecciona cada pestaña.

Importante

Se recomienda que una instancia de TabbedPage se rellene únicamente con instancias de NavigationPage y ContentPage. Esto ayuda a garantizar una experiencia de usuario coherente en todas las plataformas.

Además, TabbedPage define las propiedades siguientes:

Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que se les pueden aplicar estilos y que las propiedades pueden ser los destinos de los enlaces de datos.

Advertencia

En un elemento TabbedPage, cada objeto Page se crea cuando se construye TabbedPage. Esto puede dar lugar a una experiencia de usuario deficiente, especialmente si TabbedPage es la página raíz de la aplicación. Aun así, Xamarin.Forms Shell permite que las páginas a las que se accede mediante una barra de pestañas se creen a petición, en respuesta a la navegación. Para obtener más información, consulte Xamarin.Forms Shell.

Relleno de un elemento TabbedPage con una colección de páginas

Un elemento TabbedPage se puede rellenar con una colección de objetos Page secundarios, por ejemplo, objetos ContentPage. Para ello, se agregan los objetos Page a la colección TabbedPage.Children. Esto se puede lograr en XAML de la siguiente manera:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:TabbedPageWithNavigationPage;assembly=TabbedPageWithNavigationPage"
            x:Class="TabbedPageWithNavigationPage.MainPage">
    <local:TodayPage />
    <NavigationPage Title="Schedule" IconImageSource="schedule.png">
        <x:Arguments>
            <local:SchedulePage />
        </x:Arguments>
    </NavigationPage>
</TabbedPage>

Nota:

La propiedad Children de la clase MultiPage<T>, de la que se deriva TabbedPage, es la propiedad ContentProperty de MultiPage<T>. Por lo tanto, en XAML no es necesario asignar explícitamente los objetos Page a la propiedad Children.

El código de C# equivalente es el siguiente:

public class MainPageCS : TabbedPage
{
  public MainPageCS ()
  {
    NavigationPage navigationPage = new NavigationPage (new SchedulePageCS ());
    navigationPage.IconImageSource = "schedule.png";
    navigationPage.Title = "Schedule";

    Children.Add (new TodayPageCS ());
    Children.Add (navigationPage);
  }
}

En este ejemplo, el elemento TabbedPage se rellena con dos objetos Page. El primer elemento secundario es un objeto ContentPage y el segundo es un objeto NavigationPage que contiene un objeto ContentPage.

En las capturas de pantalla siguientes se muestra un objeto ContentPage de un elemento TabbedPage:

Screenshot of a TabbedPage containing three tabs, on iOS and Android

Al seleccionar otra pestaña se muestra el objeto ContentPage que representa la pestaña:

Screenshot of a TabbedPage containing tabs, on iOS and Android

En la pestaña Programar, el objeto ContentPage está encapsulado en un objeto NavigationPage.

Advertencia

Aunque se puede colocar un objeto NavigationPage en un elemento TabbedPage, no se recomienda colocar un elemento TabbedPage en un objeto NavigationPage. Esto se debe a que, en iOS, un elemento UITabBarController siempre actúa como contenedor de UINavigationController. Para obtener más información, vea Combined View Controller Interfaces (Interfaces combinadas del controlador de vistas) en la biblioteca para desarrolladores de iOS.

La navegación se puede realizar dentro de una pestaña, siempre y cuando el objeto ContentPage esté encapsulado en un objeto NavigationPage. Para ello, se invoca el método PushAsync en la propiedad Navigation del objeto ContentPage:

await Navigation.PushAsync (new UpcomingAppointmentsPage ());

La página a la que se navega se especifica como argumento para el método PushAsync. En este ejemplo, la página UpcomingAppointmentsPage se inserta en la pila de navegación, donde se convierte en la página activa:

Screenshot of navigation within a tab, on iOS and Android

Para obtener más información sobre la navegación mediante la clase NavigationPage, vea Navegación jerárquica.

Relleno de un elemento TabbedPage con una plantilla

Un elemento TabbedPage se puede rellenar con páginas mediante la asignación de una colección de datos a la propiedad ItemsSource y la asignación de DataTemplate a la propiedad ItemTemplate que crea una plantilla de los datos como objetos Page. Esto se puede lograr en XAML de la siguiente manera:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:TabbedPageDemo;assembly=TabbedPageDemo"
            x:Class="TabbedPageDemo.TabbedPageDemoPage"
            ItemsSource="{x:Static local:MonkeyDataModel.All}">            
  <TabbedPage.Resources>
    <ResourceDictionary>
      <local:NonNullToBooleanConverter x:Key="booleanConverter" />
    </ResourceDictionary>
  </TabbedPage.Resources>
  <TabbedPage.ItemTemplate>
    <DataTemplate>
      <ContentPage Title="{Binding Name}" IconImageSource="monkeyicon.png">
        <StackLayout Padding="5, 25">
          <Label Text="{Binding Name}" Font="Bold,Large" HorizontalOptions="Center" />
          <Image Source="{Binding PhotoUrl}" WidthRequest="200" HeightRequest="200" />
          <StackLayout Padding="50, 10">
            <StackLayout Orientation="Horizontal">
              <Label Text="Family:" HorizontalOptions="FillAndExpand" />
              <Label Text="{Binding Family}" Font="Bold,Medium" />
            </StackLayout>
            ...
          </StackLayout>
        </StackLayout>
      </ContentPage>
    </DataTemplate>
  </TabbedPage.ItemTemplate>
</TabbedPage>

El código de C# equivalente es el siguiente:

public class TabbedPageDemoPageCS : TabbedPage
{
  public TabbedPageDemoPageCS ()
  {
    var booleanConverter = new NonNullToBooleanConverter ();

    ItemTemplate = new DataTemplate (() =>
    {
      var nameLabel = new Label
      {
        FontSize = Device.GetNamedSize (NamedSize.Large, typeof(Label)),
        FontAttributes = FontAttributes.Bold,
        HorizontalOptions = LayoutOptions.Center
      };
      nameLabel.SetBinding (Label.TextProperty, "Name");

      var image = new Image { WidthRequest = 200, HeightRequest = 200 };
      image.SetBinding (Image.SourceProperty, "PhotoUrl");

      var familyLabel = new Label
      {
        FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
        FontAttributes = FontAttributes.Bold
      };
      familyLabel.SetBinding (Label.TextProperty, "Family");
      ...

      var contentPage = new ContentPage
      {
        IconImageSource = "monkeyicon.png",
        Content = new StackLayout {
          Padding = new Thickness (5, 25),
          Children =
          {
            nameLabel,
            image,
            new StackLayout
            {
              Padding = new Thickness (50, 10),
              Children =
              {
                new StackLayout
                {
                  Orientation = StackOrientation.Horizontal,
                  Children =
                  {
                    new Label { Text = "Family:", HorizontalOptions = LayoutOptions.FillAndExpand },
                    familyLabel
                  }
                },
                // ...
              }
            }
          }
        }
      };
      contentPage.SetBinding (TitleProperty, "Name");
      return contentPage;
    });
    ItemsSource = MonkeyDataModel.All;
  }
}

En este ejemplo, cada pestaña consta de un objeto ContentPage que usa objetos Image y Label para mostrar los datos de la pestaña:

Screenshot of a templated TabbedPage, on iOS and Android

Al seleccionar otra pestaña se muestra el objeto ContentPage que representa la pestaña.