この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
今回は、「Xamarinによる3種類のアプローチ」で紹介した3つのアプローチの最後であるXamarin.Formsについてです。
Xamarin.Formsは、iOS や Android のライブラリとは全くの別物であり、完全に独自のライブラリとなっています。従って、既存の知識を頼りにすることはできず、一から学ぶ必要があります。 しかし、このライブラリを使用すると、iOS、Android、Windows Phone (ストアアプリにも対応中) 用のネイティブアプリが一気に作成できてしまいます。
2 ページクラス
Xamarin.Formsで画面を構成するには、最初にページクラスを理解する必要があります。
Xamarin Developers Guide 「Xamarin.Forms Pages」
ページクラスは、画面のすべて(若しくは殆どすべて)を占有し、単一の子要素を含むビジュアル要素です。AndroidでのActivity、iOSでのView Controller、WindowsPhoneでのPageと同じようなイメージです。
Xamarin.FormsのPageクラスは、次の5つがあります。
- ContentPage
- MasterDetailPage
- NavigationPage
- TabbedPage
- CarouselPage
以下、各ページクラスを、可能な限りシンプルなサンプルで紹介したいと思います。
(1) ContentPage
iOS | Android | WindowsPhone |
単一ページとなり、Contentプロパティに任意のViewコントロールを子要素として配置できます。 複数のコントロールを配置する際には、StackLayoutやScrollViewが、よく利用されます。
App.cs
public class App : Application {
public App() {
// MyContentPagePageを継承したクラスを生成してMainPageとする
MainPage = new MyContentPage();
}
}
class MyContentPage : ContentPage {
public MyContentPage() {
//iPhoneにおいて、ステータスバーとの重なりを防ぐためパディングを調整する
Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
//ラベルを1つ生成
var label1 = new Label {
FontSize = 40,
Text = "Developers.IO"
};
// 生成したラベルをこのビューの子要素とする
Content = label1;
}
}
(2) MasterDetailPage
iOS | Android | WindowsPhone |
概要レベルで要素を一覧するマスターページと、各要素の詳細ページを管理するページです。通常、マスターページがメニュー的な役割を担うことになると思います。
App.cs
public class App : Application {
public App() {
// MasterDetailPageを継承したクラスを生成してMainPageとする
MainPage = new MyMasterDetailPage();
}
}
class MyMasterDetailPage : MasterDetailPage {
public MyMasterDetailPage() {
var ar = new[] { "Ietm1", "Item2", "Item3" };
ListView listView = new ListView {
ItemsSource = ar,
BackgroundColor = Color.Transparent
};
// マスターページ
this.Master = new ContentPage {
BackgroundColor = Color.FromRgba(0.86,0.91,0.94,0.5),
//iPhoneにおいて、ステータスバーとの重なりを防ぐためパディングを調整する
Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0),
Title = "Master", // 必須
Icon = "menu.png",
Content = listView
};
// リストが選択された際のイベント処理
listView.ItemSelected += (s, a) => {
//プロパティDetailに新しいページをセットする
Detail = new NavigationPage(new DetailPage(a.SelectedItem.ToString())) {
// タイトルバーの背景色や文字色は、NavigationPageのプロパティをセットする
BarBackgroundColor = Color.FromRgba(0.2, 0.6, 0.86, 1),
BarTextColor = Color.White
};
IsPresented = false;// Detailページを表示する
};
listView.SelectedItem = ar[0];// 必須 最初のページをセットする
}
}
//詳細ページ
class DetailPage : ContentPage {
public DetailPage(string title) {
Title = title;
Content = new Label {
//テキストを中央に表示する
Text = title,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
}
}
コメントで「必須」となっている箇所は、省略すると例外で落ちます。 また、今回、メニュー表示のために「戻る」機能を利用したくて、DetailにセットするページをNavigationPageにしましたが、これは必須ではありません。(ContentPage等でも問題ありません)
(3) NavigationPage
iOS | Android | WindowsPhone |
iOSのUINavigationControllerと同じイメージです。 遷移元に戻るには、Backボタンを使いますが、WindowsPhoneは、ハードウエアのBackしかありません。
App.cs
public class App : Application {
public App() {
// NavigationPageを使用して最初のページを表示する
MainPage = new NavigationPage(new MainPage()) {
// タイトルバーの背景色や文字色は、NavigationPageのプロパティをセットする
BarBackgroundColor = Color.FromRgba(0.2, 0.6, 0.86, 1),
BarTextColor = Color.White
};
}
}
//メインのページ
class MainPage : ContentPage {
public MainPage() {
Title = "MainPage"; //ページのタイトル
//ボタンを生成
var button1 = new Button { Text = "NextPageへ移動" };
//ボタンクリック時の処理
button1.Clicked += async (s, a) => {
//ページを遷移する
await Navigation.PushAsync(new NextPage());
};
Content = button1;
}
}
//遷移後のページ
class NextPage : ContentPage {
public NextPage() {
Title = "NextPage"; //ページのタイトル
}
}
(4) TabbedPage
iOS | Android | WindowsPhone |
タブで複数のページを切り替えるページです。ネイティブコントロールで描画されることから、タブは、iOSでは下に、Androidでは上に配置されます。 正直な感想ですが、WindowsPhoneはタブじゃない・・・
App.cs
public class App : Application {
public App() {
// TabbedPageをMainPageとしてセットする
MainPage = new TabbedPage() {
Children = {
new MyPage("Tab1"),
new MyPage("Tab2"),
new MyPage("Tab3")
}
};
}
}
class MyPage : ContentPage {
public MyPage(string title) {
//タブに表示される文字列
Title = title;
//ラベルを生成
var label1 = new Label {
FontSize = 40,
//ビューの中央に配置
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Text = title
};
Content = label1;//ラベルのみを配置する
}
}
(5) CarouselPage
iOS | Android | WindowsPhone |
スワイプによって複数のページをスライドすることができるページです。 WindowPhoneは、ここでも、ループしています。
App.cs
public class App : Application {
public App() {
// CarouselPageをMainPageとしてセットする
MainPage = new CarouselPage() {
Children = {
new MyPage(Color.Green),
new MyPage(Color.Red),
new MyPage(Color.Aqua)
}
};
}
}
class MyPage : ContentPage {
public MyPage(Color color) {
//ページの区切りが分かりやすいように背景色を設定する
BackgroundColor = color;
//ラベルを生成
var label1 = new Label {
FontSize=40,
//ビューの中央に配置
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Text = string.Format("RGB({0:0},{1:0},{2:0})", color.R, color.G, color.B)
};
Content = label1;//ラベルのみを配置する
}
}
3 まとめ
今回は、Xamarin.Formsを使用する場合に、最初に決めなければならない画面構成であるページクラスについて紹介しました。 個人的な見解ですが、さすがに3つのプラットフォームを跨ぐとなると、ちょっと無理があるものも有るなと思います。
サンプルコード(https://github.com/furuya02/Xamarin.Forms.PageSample)
本記事は、2015年10月20日現在で最新の Xamarin.Forms 1.5.1.6468 を使用して作成されています。
4 参考リンク
Xamarin Developers Guide 「Xamarin.Forms Pages」
Xamarin Forms MasterDetail Page Navigation Recipe
Xamarin.Forms で MasterDetailPage を使うには
Xamarin記事一覧(SAPPOROWORKSの覚書)