Xamarin.Forms TabbedPage
Состоит Xamarin.FormsTabbedPage
из списка вкладок и более крупной области сведений с каждой загрузкой содержимого вкладки в область сведений. На снимках экрана ниже показана страница TabbedPage
в iOS и Android.
В iOS список вкладок отображается в нижней части экрана, а также в области данных сверху. У каждой вкладки есть заголовок и значок, который должен быть PNG-файлом с альфа-каналом. В книжной ориентации значки панели вкладок отображаются над заголовками вкладок. В альбомной ориентации значки и заголовки отображаются рядом. Кроме того, в зависимости от устройства и ориентации может отображаться обычная или компактная панель вкладок. При наличии более пяти вкладок появляется вкладка Дополнительно, используемая для доступа к дополнительным вкладкам.
В Android список вкладок отображается в верхней части экрана, а также в области данных ниже. У каждой вкладки есть заголовок и значок, который должен быть PNG-файлом с альфа-каналом. Но эти вкладки можно переместить в нижнюю часть экрана в зависимости от конкретной платформы. При наличии более пяти вкладок, список которых отображается внизу экрана, появляется вкладка Дополнительно, которую можно использовать для доступа к дополнительным вкладкам. Дополнительные сведения о требованиях к значкам см. в разделах о вкладках на сайте material.io и поддержке разных значений плотности пикселей на сайте developer.android.com. Дополнительные сведения о перемещении вкладок в нижнюю часть экрана см. в статье TabbedPage Toolbar Placement and Color on Android (Цвет и размещение значков на панели TabbedPage в Android).
На универсальной платформе Windows (UWP) список вкладок отображается в верхней части экрана, а также в области данных ниже. У каждой вкладки есть заголовок. Тем не менее на каждую вкладку можно добавлять значки в зависимости от платформы. Дополнительные сведения см. в статье о значках TabbedPage в Windows.
Совет
Файлы SVG (Scalable Vector Graphic) могут отображаться в виде значков вкладок на TabbedPage
.
- Для класса
TabbedRenderer
iOS есть переопределяемый методGetIcon
, который можно использовать для загрузки значков вкладок из указанного источника. Кроме того, при необходимости можно предоставить варианты значка в выбранном и невыбранном состоянии. - У класса
TabbedPageRenderer
Android AppCompat есть переопределяемый методSetTabIconImageSource
, который может использоваться для загрузки значков вкладок из настраиваемого объектаDrawable
. Кроме того, SVG-файлы можно преобразовать в векторные прорисовываемые ресурсы, которые могут автоматически отображаться в Xamarin.Forms. Дополнительные сведения о преобразовании SVG-файлов в векторные прорисовываемые ресурсы см. в статье о добавлении векторной графики с несколькими плотностями на сайте developer.android.com.
Создание объекта TabbedPage
Создать TabbedPage
можно двумя способами:
- Заполните
TabbedPage
коллекцией дочерних объектовPage
, напримерContentPage
. Дополнительные сведения см. в разделе Заполнение TabbedPage коллекцией Page. - Назначьте коллекции свойство
ItemsSource
, а затем присвойтеDataTemplate
свойствуItemTemplate
для возврата станицы объектов в коллекции. Дополнительные сведения см. в разделе Заполнение TabbedPage с помощью шаблона.
При обоих подходах TabbedPage
отображает каждую страницу при выборе пользователем каждой из вкладок.
Внимание
Рекомендуется заполнять TabbedPage
только экземплярами NavigationPage
и ContentPage
. Это позволит обеспечить согласованность пользовательского интерфейса на всех платформах.
Кроме того, TabbedPage
определяет следующие свойства:
BarBackgroundColor
с типомColor
— цвет фона панели вкладок;BarTextColor
с типомColor
— цвет текста на панели вкладок;SelectedTabColor
с типомColor
— цвет выбранной вкладки.UnselectedTabColor
с типомColor
— цвет вкладки, если она не выбрана.
Все эти свойства поддерживаются объектами BindableProperty
, то есть к ним можно применить стиль и их можно указывать в качестве целевых для привязки данных.
Предупреждение
В TabbedPage
каждый объект Page
создается при формировании TabbedPage
. Это может повлечь проблемы с произвольностью, особенно если TabbedPage
является корневой страницей приложения. Тем не менее оболочка Xamarin.Forms позволяет по запросу создавать страницы, доступ к которым осуществляется через панель вкладок, в ответ на навигацию. Дополнительные сведения см. в разделе Оболочка Xamarin.Forms.
Заполнение TabbedPage коллекцией Page
TabbedPage
можно заполнить коллекцией дочерних объектов Page
, например ContentPage
. Для этого необходимо добавить объекты Page
в коллекцию TabbedPage.Children
. Это можно сделать в XAML следующим образом:
<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>
Примечание.
Свойство Children
класса MultiPage<T>
, из которого происходит TabbedPage
, – это свойство ContentProperty
MultiPage<T>
. Таким образом, в XAML нет необходимости явно назначать объекты Page
свойству Children
.
Эквивалентный код на C# выглядит так:
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);
}
}
В этом примере TabbedPage
заполнена двумя объектами Page
. Первый дочерний объект — это объект ContentPage
, а второй дочерний объект — NavigationPage
, содержащий объект ContentPage
.
На снимках экрана ниже показан объект ContentPage
в TabbedPage
:
При выборе другой вкладки отображается объект ContentPage
, представляющий вкладку:
На вкладке Расписание объект ContentPage
упаковывается в объект NavigationPage
.
Предупреждение
Хотя NavigationPage
можно поместить в TabbedPage
, не рекомендуется размещать TabbedPage
в NavigationPage
. Это обусловлено тем, что в iOS UITabBarController
всегда служит оболочкой для UINavigationController
. Дополнительные сведения см. в разделе Комбинированные интерфейсы контроллера представления библиотеки разработчика iOS.
Перемещение в пределах вкладки
Навигацию можно осуществлять в пределах одной вкладки при условии, что объект ContentPage
упакован в объект NavigationPage
. Для этого необходимо вызвать метод PushAsync
для свойства Navigation
объекта ContentPage
:
await Navigation.PushAsync (new UpcomingAppointmentsPage ());
Страница, к которой осуществляется переход, указывается в качестве аргумента метода PushAsync
. В этом примере страница UpcomingAppointmentsPage
принудительно отправляется в стек навигации, где становится активной:
Дополнительные сведения об осуществлении навигации с помощью класса NavigationPage
см. в статье Иерархическая навигация.
Заполнение TabbedPage с помощью шаблона
TabbedPage
можно заполнить страницами, назначив коллекцию данных свойству ItemsSource
, а также назначив DataTemplate
свойству ItemTemplate
, которое записывает данные в шаблон в виде объектов Page
. Это можно сделать в XAML следующим образом:
<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>
Эквивалентный код на C# выглядит так:
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;
}
}
В этом примере каждая вкладка состоит из объекта ContentPage
, который использует объекты Image
и Label
для вывода данных на вкладку:
При выборе другой вкладки отображается объект ContentPage
, представляющий вкладку.