Xamarin.Formsで画面の左側から出てくるメニュー(いわゆる「ハンバーガーメニュー」)を作ってみよう。そして、メニューで選択した画面に遷移させる。次の画像のような画面だ。
このような画面を作るには、MasterDetailPageコントロールを使う。MasterDetailPageコントロールには、2つのPageコントロールを収めるセクションがある。「Master」と「Detail」だ。ただし、左から出てくるメニュー部分が「Master」で、上の画像で赤や緑の色が付いている部分が「Detail」である。
そして、「Detail」に収めるPageコントロールとしてNavigationPageコントロールを使えば、「Detail」の中だけを画面遷移させられる。
では、作ってみよう。以下で説明するコードの全体は、「Microsoft Developer Network > サンプル > Xamarin入門#02 HamburgerMenu」からダウンロードできる。
"Hello, Xamarin!"アプリと同様にして、プロジェクトテンプレートに[Blank Xaml App (Xamarin.Forms Portable)]を選んでソリューションを作る。プロジェクト名は「HamburgerMenu」とする。
まずは、「Detail」画面の中に表示する画面から作ろう。PCLプロジェクトに[Forms Xaml Page]を3つ追加する([新しい項目の追加]ダイアログで[Cross-Platform]セクションにある)。ファイル名は「DetailPage1.xaml」/「DetailPage2.xaml」/「DetailPage3.xaml」とする。「DetailPage1.xaml」ファイルは次のコードのように編集する。残りの2つも同じように、ただし、見た目で区別できるように編集しておく。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="HamburgerMenu.DetailPage1"
Title="Hamburger Menu Page-01"
BackgroundColor="#22ff0000"
>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<!--<Label Text="{Binding MainText}" VerticalOptions="Center"
HorizontalOptions="Center" />-->
<Label Text="DetailPage1" VerticalOptions="Center" HorizontalOptions="Center"
FontSize="Large"/>
</ContentPage>
次に、「Master」の中に表示するメニュー画面を作ろう。PCLプロジェクトに[Forms Xaml Page]を1つ追加し、ファイル名を「MasterPage.xaml」とする。「MasterPage.xaml」ファイルは次のコードのように編集する。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="HamburgerMenu.MasterPage"
Title="MENU"
>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="20"
Android="0" WinPhone="20,0,20,0" />
</ContentPage.Padding>
<!--<Label Text="{Binding MainText}" VerticalOptions="Center"
HorizontalOptions="Center" />-->
<TableView Intent="Menu" RowHeight="60">
<TableView.Root>
<TableSection Title="メニュー" >
<TextCell Text="Page 1" TextColor="Accent" Tapped="Menu1_Tapped" />
<TextCell Text="Page 2" TextColor="Accent" Tapped="Menu2_Tapped" />
<TextCell Text="Page 3" TextColor="Accent" Tapped="Menu3_Tapped" />
</TableSection>
</TableView.Root>
</TableView>
</ContentPage>
上のコードには、コードビハインドにイベントハンドラーが必要だが、それは後ほど解説する。
最後の画面を作ろう。MasterDetailPage画面だ。これは、プロジェクト作成時に自動生成された「MainPage.xaml」ファイルを、次のコードのように編集する。
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:HamburgerMenu"
x:Class="HamburgerMenu.MainPage"
MasterBehavior="Popover"
>
<!--<Label Text="Welcome to Xamarin Forms!" VerticalOptions="Center"
HorizontalOptions="Center" />-->
<MasterDetailPage.Master>
<local:MasterPage />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<local:DetailPage1 />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
また、「MainPage.xaml.cs」ファイルも、次のコードのように親クラスを変更する。
……省略……
public partial class MainPage : MasterDetailPage
{
public MainPage()
{
……省略……
これで画面がそろった。
最後に、MasterPage画面(=メニューの内容)のコードビハインドに、メニューを選んだときのイベントハンドラーを実装する。<MasterDetailPage.Detail>要素に入っているNavigationPageコントロールのNavigationプロパティに対してPushAsyncメソッドを呼び出すと、画面遷移するのだ(詳しくは「.NET TIPS:Xamarin.Forms:画面遷移するには?」を参照)。
「MasterPage.xaml.cs」ファイルを次のコードのように編集する。
……省略……
public partial class MasterPage : ContentPage
{
public MasterPage()
{
InitializeComponent();
}
// Detailページを画面遷移させるメソッド
void Navigate<P>() where P: Page, new()
{
// MainPageオブジェクトを取り出す
var mainPage = this.Parent as MainPage;
// MainPageのDetailセクションに入っているページオブジェクトを取り出す
var detail = mainPage.Detail;
if (detail.Navigation.NavigationStack.LastOrDefault() is P)
return; //現在表示中と同じページなら、画面遷移しない
// 画面遷移する
detail.Navigation.PushAsync(new P(), true);
// メニューを閉じる
mainPage.IsPresented = false;
}
// イベントハンドラー
protected void Menu1_Tapped(object sender, EventArgs e)
=> Navigate<DetailPage1>();
protected void Menu2_Tapped(object sender, EventArgs e)
=> Navigate<DetailPage2>();
protected void Menu3_Tapped(object sender, EventArgs e)
=> Navigate<DetailPage3>();
}
……省略……
以上で完成である。実行してみると次の画像のようになる([DetailPage3]に遷移した状態)。
上の3つの画像を見て気が付かれただろうか? 自動的にプラットフォームに応じたUIになっているのだ。Androidでは、前の画面に戻るためのボタンが左上に表示されている。iOSでは、リンクだ。Windows Phoneでは[戻る]ボタンは表示されていないが、NavigationPageクラスを利用したことでハードウェアの[戻る]ボタンに対応している。
Xamarin.Formsのコントロールを使うと、このようにプラットフォームに応じたUIになるのである。
Copyright© Digital Advantage Corp. All Rights Reserved.