TabbedPage de Xamarin.Forms
Xamarin.FormsTabbedPage
consta de una lista de pestañas y un área de detalles más grande y cada pestaña carga contenido en el área de detalles. En las capturas de pantalla siguientes se muestra un elemento TabbedPage
en iOS y 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 reemplazableGetIcon
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 reemplazableSetTabIconImageSource
que se puede usar para cargar iconos de pestaña desde un elementoDrawable
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.
Creación de TabbedPage
Para crear una instancia de TabbedPage
se pueden usar dos métodos:
- Rellene el elemento
TabbedPage
con una colección de objetosPage
secundarios, por ejemplo, objetosContentPage
. Para más información, consulte Relleno de un elemento TabbedPage con una colección de páginas. - Asigne una colección a la propiedad
ItemsSource
y asigne un elementoDataTemplate
a la propiedadItemTemplate
para devolver páginas para los objetos de la colección. Para más información, consulte Relleno de un elemento TabbedPage con una plantilla.
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:
BarBackgroundColor
de tipoColor
, el color de fondo de la barra de pestañas.BarTextColor
de tipoColor
, el color del texto de la barra de pestañas.SelectedTabColor
de tipoColor
, el color de la pestaña cuando está seleccionada.UnselectedTabColor
de tipoColor
, el color de la pestaña cuando no está seleccionada.
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
:
Al seleccionar otra pestaña se muestra el objeto ContentPage
que representa la pestaña:
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.
Navegación en una pestaña
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:
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:
Al seleccionar otra pestaña se muestra el objeto ContentPage
que representa la pestaña.