Xamarin.Forms FlyoutPage
플라이아웃 페이지는 일반적으로 다음 스크린샷과 같이 항목 목록을 표시합니다.
항목 목록의 위치는 각 플랫폼에서 동일하며, 항목 중 하나를 선택하면 해당 세부 정보 페이지로 이동합니다. 또한 플라이아웃 페이지에는 활성 세부 정보 페이지로 이동하는 데 사용할 수 있는 단추가 포함된 탐색 모음이 있습니다.
- iOS의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 세부 정보 페이지로 이동하는 단추가 있습니다. 또한 플라이아웃을 왼쪽으로 살짝 밀어 활성 세부 정보 페이지로 이동할 수 있습니다.
- Android의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 제목, 아이콘 및 세부 정보 페이지로 이동하는 단추가 표시됩니다. 아이콘은 Android 플랫폼 관련 프로젝트의
MainActivity
클래스를 데코레이팅하는[Activity]
특성에 정의됩니다. 플라이아웃 페이지를 왼쪽으로 살짝 밀거나, 화면의 오른쪽 끝에 있는 세부 정보 페이지를 탭하거나, 화면의 아래쪽에 있는 ‘뒤로’ 단추를 탭하여 활성 세부 정보 페이지로 이동할 수도 있습니다. - UWP(유니버설 Windows 플랫폼)의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 세부 정보 페이지로 이동하는 단추가 있습니다.
세부 정보 페이지에는 플라이아웃 페이지에서 선택한 항목에 해당하는 데이터가 표시됩니다. 다음 스크린샷에는 세부 정보 페이지의 주요 구성 요소가 나와 있습니다.
세부 정보 페이지에는 콘텐츠가 플랫폼에 따라 달라지는 탐색 모음이 있습니다.
- iOS의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 제목이 표시되고, 세부 정보 페이지 인스턴스가
NavigationPage
인스턴스에 래핑된 경우 플라이아웃 페이지로 돌아가는 단추가 있습니다. 세부 정보 페이지를 오른쪽으로 살짝 밀어서 플라이아웃 페이지로 돌아갈 수도 있습니다. - Android의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 제목, 아이콘 및 플라이아웃 페이지로 돌아가는 단추가 표시됩니다. 아이콘은 Android 플랫폼 관련 프로젝트의
MainActivity
클래스를 데코레이팅하는[Activity]
특성에 정의됩니다. - UWP의 경우 탐색 모음이 페이지의 위쪽에 있으며, 여기에는 제목이 표시되고, 플라이아웃 페이지로 돌아가는 단추가 있습니다.
탐색 동작
플라이아웃 페이지와 세부 정보 페이지 간의 탐색 동작은 플랫폼에 따라 다릅니다.
- iOS의 경우 플라이아웃 페이지를 왼쪽에서 밀면 세부 정보 페이지가 오른쪽으로 ‘밀리고’ 세부 정보 페이지의 왼쪽 부분이 계속 표시됩니다.
- Android의 경우 세부 정보 페이지와 플라이아웃 페이지가 서로 ‘겹쳐집니다’.
- UWP의 경우 플라이아웃 페이지는
FlyoutLayoutBehavior
속성이Popover
로 설정된 경우 세부 정보 페이지의 남은 부분에서 슬라이드됩니다.
iOS와 Android의 플라이아웃 페이지가 세로 모드의 플라이아웃 페이지와 비슷한 너비를 갖고 있으므로 더 많은 세부 페이지가 표시된다는 점을 제외하고는 가로 모드에서도 이와 비슷한 동작이 관찰됩니다.
탐색 동작을 제어하는 방법에 대한 자세한 내용은 세부 정보 페이지 레이아웃 동작 제어를 참조하세요.
FlyoutPage 만들기
FlyoutPage
는 각각 플라이아웃 페이지와 세부 정보 페이지를 가져오고 설정하는 데 사용되는 Page
형식의 Flyout
및 Detail
속성을 포함합니다.
Important
FlyoutPage
는 루트 페이지로 설계되었으며, 이 페이지를 다른 페이지 형식의 자식 페이지로 사용하면 예기치 않고 일관되지 않은 동작이 발생할 수 있습니다. 또한 FlyoutPage
의 플라이아웃 페이지는 항상 ContentPage
인스턴스여야 하며 세부 정보 페이지는 TabbedPage
, NavigationPage
및 ContentPage
인스턴스로 채우는 것이 좋습니다. 이렇게 하면 모든 플랫폼에서 일관된 사용자 환경을 보장하는 데 도움이 됩니다.
다음 XAML 코드 예제에서는 Flyout
및 Detail
속성을 설정하는 FlyoutPage
를 보여 줍니다.
<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>
다음 코드 예제에서는 C#에서 만든 해당 FlyoutPage
를 보여줍니다.
public class MainPageCS : FlyoutPage
{
FlyoutMenuPageCS flyoutPage;
public MainPageCS()
{
flyoutPage = new FlyoutMenuPageCS();
Flyout = flyoutPage;
Detail = new NavigationPage(new ContactsPageCS());
...
}
...
}
Flyout
속성이 ContentPage
인스턴스로 설정됩니다. Detail
속성이 ContentPage
인스턴스가 포함된 NavigationPage
로 설정됩니다.
플라이아웃 페이지 만들기
다음 XAML 코드 예제에서는 Flyout
속성을 통해 참조되는 FlyoutMenuPage
개체의 선언을 보여 줍니다.
<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>
이 페이지는 해당 ItemsSource
속성을 FlyoutPageItem
개체의 배열로 설정하여 XAML 형식 데이터로 채워지는 ListView
로 구성됩니다. 각 FlyoutPageItem
은 Title
, IconSource
및 TargetType
속성을 정의합니다.
DataTemplate
은 각각의 FlyoutPageItem
을 표시하기 위해 ListView.ItemTemplate
속성에 할당됩니다. DataTemplate
에는 Image
및 Label
로 구성된 ViewCell
이 포함됩니다. Image
에는 IconSource
속성 값이 표시되고, Label
에는 각 FlyoutPageItem
에 대한 Title
속성 값이 표시됩니다.
이 페이지에는 해당 Title
및 IconImageSource
속성이 설정되어 있습니다. 세부 정보 페이지에 제목 표시줄이 있으면 아이콘이 세부 정보 페이지에 표시됩니다. 세부 정보 페이지 인스턴스를 NavigationPage
인스턴스에 래핑하여 iOS에서 이를 활성화해야 합니다.
다음 코드 예제에서는 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 }
};
}
}
다음 스크린샷에서는 각 플랫폼의 플라이아웃 페이지를 보여 줍니다.
세부 정보 페이지 만들기 및 표시
MainPage
FlyoutPage
인스턴스가 ItemSelected
이벤트를 처리할 이벤트 처리기를 등록할 수 있도록 FlyoutMenuPage
인스턴스에는 해당 ListView
인스턴스를 공개하는 ListView
속성이 포함됩니다. 이렇게 하면 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
메서드에서 수행하는 작업은 다음과 같습니다.
ListView
인스턴스에서SelectedItem
을 검색하여null
이 아닌 경우 세부 정보 페이지를FlyoutPageItem
의TargetType
속성에 저장된 페이지 형식의 새 인스턴스로 설정합니다.FlyoutMenuPage
의IconImageSource
속성을 통해 참조된 아이콘이 iOS의 세부 정보 페이지에 표시되도록 페이지 형식이NavigationPage
인스턴스에 래핑됩니다.- 다음에
FlyoutMenuPage
가 표시되면ListView
항목이 선택되지 않도록ListView
에서 선택한 항목이null
로 설정됩니다. - 세부 정보 페이지는
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>
다음 코드 예제에서는 C#에서 만든 해당 FlyoutPage
를 보여줍니다.
public class MainPageCS : FlyoutPage
{
FlyoutMenuPageCS flyoutPage;
public MainPageCS()
{
...
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
}
}
Important
FlyoutLayoutBehavior
속성의 값은 태블릿 또는 데스크톱에서 실행되는 애플리케이션에만 영향을 줍니다. 휴대폰에서 실행되는 애플리케이션에는 항상 동작이 있습니다 Popover
.