FlyoutPage в Xamarin.Forms
На всплывающей странице обычно отображается список элементов, как показано на следующих снимках экрана:
Расположение списка элементов одинаково для каждой платформы, а при выборе отдельного элемента осуществляется переход на соответствующую страницу сведений. Кроме того, на всплывающей странице также представлена панель навигации с кнопкой, позволяющей перейти к активной странице сведений:
- В iOS панель навигации располагается в верхней части страницы и содержит кнопку для перехода на страницу сведений. Кроме того, для перехода на активную страницу сведений можно провести пальцем по всплывающему элементу влево.
- В Android панель навигации располагается в верхней части страницы и содержит заголовок, значок, а также кнопку для перехода на страницу сведений. Значок определяется в атрибуте
[Activity]
, который оформляет классMainActivity
в проекте, зависящем от платформы Android. Кроме того, для перехода на активную страницу сведений можно провести по всплывающей странице влево, коснуться страницы сведений в крайней правой части экрана и коснуться кнопки Назад внизу экрана. - На универсальной платформе Windows (UWP) панель навигации располагается в верхней части страницы и содержит кнопку для перехода на страницу сведений.
Страница сведений с данными, соответствующими выбранному на всплывающей странице элементу, а также основные компоненты страницы сведений показаны на следующих снимках экрана:
На странице сведений располагается панель навигации, содержимое которой зависит от платформы:
- На iOS панель навигации находится в верхней части страницы и содержит заголовок, а также кнопку для возврата на всплывающую страницу при условии, что экземпляр страницы сведений находится внутри экземпляра
NavigationPage
. Кроме того, для возврата на всплывающую страницу можно провести по странице сведений вправо. - На Android панель навигации находится в верхней части страницы, где отображаются заголовок, значок и кнопка для возврата на всплывающую страницу. Значок определяется в атрибуте
[Activity]
, который оформляет классMainActivity
в проекте, зависящем от платформы Android. - На универсальной платформе Windows (UWP) панель навигации находится в верхней части страницы, где отображаются заголовок и кнопка для возврата на всплывающую страницу.
Выполнение переходов
Реакция на события перехода между всплывающей страницей и страницами сведений зависит от платформы:
- На iOS страница сведений сдвигается вправо, а всплывающая страница выдвигается слева. При этом левая часть страницы сведений по-прежнему остается видимой.
- На Android всплывающая страница и страницы сведений накладываются друг на друга.
- На UWP всплывающая страница выдвигается слева и частично накладывается на страницу сведений при условии, что свойство
FlyoutLayoutBehavior
имеет значениеPopover
.
То же самое будет происходить в альбомной ориентации, только на iOS и Android всплывающая страница будет иметь примерно ту же ширину, что и в книжной, позволяя увидеть больше содержимого страницы сведений.
Дополнительные сведения: Управление разметкой страницы сведений.
Создание FlyoutPage
Страница FlyoutPage
содержит свойства Flyout
и Detail
типа Page
, которые используются для получения и задания соответственно всплывающей страницы и страниц сведений.
Внимание
Объект FlyoutPage
должен представлять корневую страницу. Если использовать его в качестве дочерней или какой-либо другой страницы, это может привести к непредвиденному или несогласованному поведению. Кроме того, рекомендуется всегда использовать в качестве всплывающей страницы FlyoutPage
экземпляр ContentPage
, а для заполнения страницы сведений использовать только экземпляры TabbedPage
, NavigationPage
и ContentPage
. Это позволит обеспечить согласованность пользовательского интерфейса на всех платформах.
В следующем примере показан код XAML для объекта FlyoutPage
, который задает свойства Flyout
и Detail
:
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FlyoutPageNavigation;assembly=FlyoutPageNavigation"
x:Class="FlyoutPageNavigation.MainPage">
<FlyoutPage.Flyout>
<local:FlyoutMenuPage x:Name="flyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<local:ContactsPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
В следующем примере кода создается эквивалентный объект FlyoutPage
на языке C#:
public class MainPageCS : FlyoutPage
{
FlyoutMenuPageCS flyoutPage;
public MainPageCS()
{
flyoutPage = new FlyoutMenuPageCS();
Flyout = flyoutPage;
Detail = new NavigationPage(new ContactsPageCS());
...
}
...
}
Свойство Flyout
содержит экземпляр ContentPage
. Свойство Detail
содержит объект NavigationPage
, содержащий экземпляр ContentPage
.
Создание всплывающей страницы
В следующем примере кода XAML показано объявление объекта FlyoutMenuPage
, на который задаются ссылки посредством свойства Flyout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="using:FlyoutPageNavigation"
x:Class="FlyoutPageNavigation.FlyoutMenuPage"
Padding="0,40,0,0"
IconImageSource="hamburger.png"
Title="Personal Organiser">
<StackLayout>
<ListView x:Name="listView" x:FieldModifier="public">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:FlyoutPageItem}">
<local:FlyoutPageItem Title="Contacts" IconSource="contacts.png" TargetType="{x:Type local:ContactsPage}" />
<local:FlyoutPageItem Title="TodoList" IconSource="todo.png" TargetType="{x:Type local:TodoListPage}" />
<local:FlyoutPageItem Title="Reminders" IconSource="reminders.png" TargetType="{x:Type local:ReminderPage}" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1" Text="{Binding Title}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Эта страница содержит объект ListView
, который заполняется данными в XAML. Для этого его свойству ItemsSource
присваивается массив объектов FlyoutPageItem
. Каждый объект FlyoutPageItem
определяет свойства Title
, IconSource
и TargetType
.
Объект DataTemplate
присваивается свойству ListView.ItemTemplate
для отображения каждого объекта FlyoutPageItem
. Объект DataTemplate
содержит объект ViewCell
, который состоит из объектов Image
и Label
. Объект Image
отображает значение свойства IconSource
, а объект Label
отображает значение свойства Title
для каждого объекта FlyoutPageItem
.
Для этой страницы заданы свойства Title
и IconImageSource
. Если у страницы сведений есть заголовок, на ней появится значок. Чтобы реализовать это в iOS, необходимо упаковать экземпляр страницы сведений в экземпляр NavigationPage
.
В следующем примере кода создается эквивалентная страница на языке C#:
public class FlyoutMenuPageCS : ContentPage
{
ListView listView;
public ListView ListView { get { return listView; } }
public FlyoutMenuPageCS()
{
var flyoutPageItems = new List<FlyoutPageItem>();
flyoutPageItems.Add(new FlyoutPageItem
{
Title = "Contacts",
IconSource = "contacts.png",
TargetType = typeof(ContactsPageCS)
});
flyoutPageItems.Add(new FlyoutPageItem
{
Title = "TodoList",
IconSource = "todo.png",
TargetType = typeof(TodoListPageCS)
});
flyoutPageItems.Add(new FlyoutPageItem
{
Title = "Reminders",
IconSource = "reminders.png",
TargetType = typeof(ReminderPageCS)
});
listView = new ListView
{
ItemsSource = flyoutPageItems,
ItemTemplate = new DataTemplate(() =>
{
var grid = new Grid { Padding = new Thickness(5, 10) };
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
var image = new Image();
image.SetBinding(Image.SourceProperty, "IconSource");
var label = new Label { VerticalOptions = LayoutOptions.FillAndExpand };
label.SetBinding(Label.TextProperty, "Title");
grid.Children.Add(image);
grid.Children.Add(label, 1, 0);
return new ViewCell { View = grid };
}),
SeparatorVisibility = SeparatorVisibility.None
};
IconImageSource = "hamburger.png";
Title = "Personal Organiser";
Padding = new Thickness(0, 40, 0, 0);
Content = new StackLayout
{
Children = { listView }
};
}
}
На следующих снимках экрана показаны всплывающие страницы на каждой платформе:
Создание и отображение страницы сведений
Экземпляр FlyoutMenuPage
содержит свойство ListView
, которое предоставляет экземпляр ListView
, благодаря чему экземпляр MainPage
FlyoutPage
может зарегистрировать обработчик для события ItemSelected
. Это позволяет экземпляру MainPage
присвоить свойству Detail
страницу, которая представляет выбранный элемент ListView
. В следующем примере кода показан обработчик событий:
public partial class MainPage : FlyoutPage
{
public MainPage()
{
...
flyoutPage.listView.ItemSelected += OnItemSelected;
}
void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as FlyoutPageItem;
if (item != null)
{
Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType));
flyoutPage.listView.SelectedItem = null;
IsPresented = false;
}
}
}
Метод OnItemSelected
выполняет следующие действия:
- Извлекает объект
SelectedItem
из экземпляраListView
и, если он не имеет значениеnull
, устанавливает в качестве страницы сведений новый экземпляр типа страницы, хранящегося в свойствеTargetType
объектаFlyoutPageItem
. Тип страницы упаковывается в экземплярNavigationPage
, чтобы обеспечить возможность ссылаться на значок посредством свойстваIconImageSource
на объектеFlyoutMenuPage
, который отображается на главной странице в iOS. - Элемент, выбранный в объекте
ListView
, получает значениеnull
. Это позволяет гарантировать, что в следующий раз при отображении объектаFlyoutMenuPage
не будет выбран ни один из элементов объектаListView
. - Для отображения страницы сведений пользователю свойства
FlyoutPage.IsPresented
присваивается значениеfalse
. Это свойство определяет, отображается ли всплывающая страница или страница сведений. Если оно имеет значениеtrue
, то отображается всплывающая страница, а значениеfalse
позволяет отобразить страницу сведений.
На следующих снимках экрана показана страница сведений ContactPage
, которая выводится на экран после выбора соответствующего элемента на всплывающей странице:
Управление разметкой страницы сведений
Принципы управления всплывающей страницей и страницами сведений для FlyoutPage
зависят от того, работает ли приложение на телефоне или планшете, от ориентации устройства, а также от значения свойства FlyoutLayoutBehavior
. Это свойство определяет, каким образом будет отображаться страница сведений. Возможные значения:
Default
— Страницы отображаются с помощью платформы по умолчанию.Popover
— страница сведений полностью или частично перекрывает всплывающую страницу.Split
— всплывающая страница отображается слева, а страница сведений находится справа.SplitOnLandscape
— разделенный экран используется, когда устройство находится в альбомной ориентации.SplitOnPortrait
— разделенный экран используется, когда устройство находится в книжной ориентации.
В следующем примере кода XAML показано, как задать свойство FlyoutLayoutBehavior
на объекте FlyoutPage
:
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FlyoutPageNavigation.MainPage"
FlyoutLayoutBehavior="Popover">
...
</FlyoutPage>
В следующем примере кода создается эквивалентный объект FlyoutPage
на языке C#:
public class MainPageCS : FlyoutPage
{
FlyoutMenuPageCS flyoutPage;
public MainPageCS()
{
...
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
}
}
Внимание
Значение свойства FlyoutLayoutBehavior
влияет только на приложения, работающие на компьютерах или планшетах. Приложения, работающие на телефонах, всегда имеют Popover
поведение.