Xamarin.Forms FlyoutPage
通常、ポップアップ ページには、次のスクリーンショットのように、項目の一覧が表示されます。
項目の一覧の場所は各プラットフォームで同じであり、いずれかの項目を選択すると対応する詳細ページに移動します。 さらに、ポップアップ ページのナビゲーション バーに含まれるボタンを使用してアクティブな詳細ページに移動することもできます。
- iOS では、ナビゲーション バーはページの上部にあり、詳細ページに移動するボタンが含まれます。 さらに、ポップアップを左にスワイプすることで、アクティブな詳細ページに移動できます。
- Android では、ナビゲーション バーはページの上部にあり、タイトル、アイコン、詳細ページに移動するボタンが表示されます。 Android プラットフォーム固有プロジェクトでは、アイコンは
MainActivity
クラスを修飾する[Activity]
属性で定義されています。 さらに、ポップアップ ページを左にスワイプするか、画面右端の詳細ページをタップするか、画面の下部にある [戻る] ボタンをタップすることによって、アクティブな詳細ページに移動できます。 - ユニバーサル Windows プラットフォーム (UWP) では、ナビゲーション バーはページの上部にあり、詳細ページに移動するボタンが含まれます。
次のスクリーンショットのように、詳細ページには、ポップアップ ページで選択されている項目に対応するデータと、詳細ページの主要コンポーネントが表示されます。
詳細ページにはナビゲーション バーが含まれ、その内容はプラットフォームによって異なります。
- iOS では、ナビゲーション バーはページの上部に存在し、タイトルが表示されています。また、詳細ページのインスタンスが
NavigationPage
インスタンスにラップされている場合は、ポップアップ ページに戻るボタンがあります。 さらに、ポップアップ ページには、詳細ページを右にスワイプすることによって戻ることができます。 - Android では、ナビゲーション バーはページの上部にあり、タイトル、アイコン、ポップアップ ページに戻るボタンが表示されます。 Android プラットフォーム固有プロジェクトでは、アイコンは
MainActivity
クラスを修飾する[Activity]
属性で定義されています。 - UWP では、ナビゲーション バーはページの上部にあり、タイトルが表示され、ポップアップ ページに戻るボタンがあります。
ナビゲーションの動作
ポップアップ ページと詳細ページの間のナビゲーション エクスペリエンスの動作は、プラットフォームによって異なります。
- iOS では、ポップアップ ページが左から "スライド" してくると、詳細ページは右にスライドしますが、詳細ページの左の部分はまだ表示されています。
- Android では、詳細ページとポップアップ ページは相互に "オーバーレイ" されます。
- UWP では、ポップアップ ページが左からスライドして詳細ページの一部を覆います。ただし、
FlyoutLayoutBehavior
プロパティがPopover
に設定されている場合です。
横モードでの動作も同様ですが、iOS と Android のポップアップ ページは縦モードのポップアップ ページと同じ幅なので、表示される詳細ページの部分が多くなります。
ナビゲーション動作の制御の詳細については、「詳細ページのレイアウト動作を制御する」をご覧ください。
FlyoutPage を作成する
FlyoutPage
には Flyout
プロパティと Detail
プロパティ (どちらも Page
型) が含まれ、それぞれ、ポップアップ ページと詳細ページの取得と設定に使用されます。
重要
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 のコード例は、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>
ページは、ItemsSource
プロパティに FlyoutPageItem
オブジェクトの配列を設定することによって XAML のデータを設定された ListView
で構成されます。 各 FlyoutPageItem
では、Title
、IconSource
、および TargetType
プロパティが定義されています。
各 FlyoutPageItem
を表示するため、DataTemplate
が ListView.ItemTemplate
プロパティに割り当てられます。 DataTemplate
には、Image
と Label
で構成される ViewCell
が含まれます。 各 FlyoutPageItem
について、Image
では IconSource
プロパティの値が表示され、Label
では Title
プロパティの値が表示されます。
ページでは、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
メソッドでは、次の操作が実行されます。
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 コードの例では、FlyoutPage
で FlyoutLayoutBehavior
プロパティを設定する方法を示します。
<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;
}
}
重要
FlyoutLayoutBehavior
プロパティの値の影響を受けるのは、タブレットまたはデスクトップで実行されているアプリケーションに限られます。 スマートフォンで実行されているアプリケーションは、常に Popover
動作になります。