Xamarin.Forms レイアウト(Formsを使用したアプリ作成の次の1歩)
1 レイアウト
アプリの画面を作成する場合、画面上に各種のコントロールを配置していく事になると思いますが、この「配置」をサポートするのが「レイアウト」です。
レイアウトは、ページやビュー上に複数のコントロールを配置するためのコンテナです。
Xamarin.Formsには、7種類のレイアウトクラスがあります。 そして、このうち、複数の子要素を格納できるプロパティーであるChildrenを持つのは、次の4種類です。
- StackLayout
- AbsoluteLayout
- Grid
- RelativeLayout
残りの3つは、単一の子要素しか格納できないプロパティーであるContentを持つため、1つの子要素を装飾するだけという位置づけになります。
- Frame
- ContentView
- ScrollView
Xamarin Developers Guide 「Xamarin.Forms Layouts」
今回も、可能な限りシンプルなサンプルコードで、この7種類のレイアウトを紹介したいと思います。
(1) StackLayout
iOS | Android | WindowsPhone |
スタックレイアウトは、子要素を縦(デフォルト)または横に並べるレイアウトです。 要素間のスペースは、レイアウト側で指定しますが、余白を全部利用するかどうか(ドッキング状態)は、子要素側のプロパティーで決定されます。
public class App : Application { public App() { //ラベルを3つ配置したスタックレイヤを生成する var stackLayout = new StackLayout { Padding = new Thickness(10, Device.OnPlatform(20, 10, 10), 10, 10), Spacing = 5, //各要素間のスペース Children ={new Label{ FontSize=30, Text = "First", HeightRequest=100,// 高さ100 BackgroundColor = Color.FromHex("82DADA"), }, new Label{ FontSize=30, Text = "Second", VerticalOptions = LayoutOptions.FillAndExpand,//縦方向に余白を最大限利用する BackgroundColor = Color.FromHex("53CF9E"), }, new Label{ FontSize=30, Text = "Third", HeightRequest=300,// 高さ300 BackgroundColor = Color.FromHex("EB6379"), }, } }; MainPage = new ContentPage { Content = stackLayout }; } }
(2) AbsoluteLayout
iOS | Android | WindowsPhone |
アブソレートレイアウトは、子要素の配置を固定座標で指定するレイアウトです。 指定要領には、範囲指定(Rectangle)、基準座標(Point)の2種類があります。
public class App : Application { public App() { //アブソレートレイアウトの生成 var absoluteLayout = new AbsoluteLayout(); //ラベルの生成とレイアウトへの追加(Rectangle指定) var label1 = new Label { Text = "First", BackgroundColor = Color.FromHex("82DADA"), FontSize = 20 }; absoluteLayout.Children.Add(label1, new Rectangle(20, 20, 200, 200)); //ラベルの生成とレイアウトへの追加(Point指定) var label2 = new Label { Text = "Second", BackgroundColor = Color.FromHex("53CF9E"), FontSize = 20 }; absoluteLayout.Children.Add(label2, new Point(200, 300)); //ラベルの生成とレイアウトへの追加(SetLayoutBounds指定) var label3 = new Label { Text = "Third", BackgroundColor = Color.FromHex("EB6379"), FontSize = 20 }; absoluteLayout.Children.Add(label3); AbsoluteLayout.SetLayoutBounds(label3, new Rectangle(30, 400, 250, 100)); MainPage = new ContentPage { Content = absoluteLayout }; } }
(3) Grid
iOS | Android | WindowsPhone |
グリッドは、複数の子要素を、行・列に基づいて配置していくレイアウトです。
public class App : Application { public App() { //グリッドの生成 var grid = new Grid { Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 10),//パディング RowSpacing = 10, //縦のスペース ColumnSpacing = 5, //横のスペース RowDefinitions = {//縦に2列 new RowDefinition { Height = GridLength.Auto },//(高さ)自動調整 new RowDefinition { Height = new GridLength(100, GridUnitType.Star) }//(高さ)のこり全部 }, ColumnDefinitions = {//横に3カラム new ColumnDefinition { Width = GridLength.Auto }, //(幅)自動調整 new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute) },//(幅)絶対値 new ColumnDefinition { Width = new GridLength(10, GridUnitType.Star) }//(幅)のこり全部 } }; //1列目にラベルを追加 grid.Children.Add(new Label { Text = "1-1", BackgroundColor = Color.Red, }, 0, 0);//1列目で左から1カラム目 grid.Children.Add(new Label { Text = "1-2", BackgroundColor = Color.Blue }, 1, 0);//1列目で左から2カラム目 grid.Children.Add(new Label { Text = "1-3", BackgroundColor = Color.Green }, 2, 0);//1列目で左から3カラム目 //2列目にラベルを追加 grid.Children.Add(new Label { Text = "2-1", BackgroundColor = Color.Yellow }, 0, 2, 1, 2); //2列目で左から1~2カラム grid.Children.Add(new Label { Text = "2-2", BackgroundColor = Color.Purple }, 2, 1);//2列目で左から3カラム目 MainPage = new ContentPage { Content = grid }; } }
(4) RelativeLayout
iOS | Android | WindowsPhone |
リラティブレイアウトは、子要素を相対的に配置するレイアウトです。 相対位置の配置方法は、「親を基準に配置する方法」と「別の子要素を基準に配置する方法」の2種類があります。
public class App : Application { public App() { //リラティブレイアウトの生成 var relativeLayout = new RelativeLayout(); //ラベルの追加 var label1 = new Label { Text = "label1", BackgroundColor = Color.FromHex("82DADA") ,FontSize=60}; relativeLayout.Children.Add(label1, //X座標は、30 Constraint.Constant(30), // Y座標は中央 (親要素との相対位置で配置) Constraint.RelativeToParent(parent => parent.Height / 2) ); //ラベルの追加 var label2 = new Label { Text = "label2", BackgroundColor = Color.FromHex("53CF9E"),FontSize=40 }; relativeLayout.Children.Add(label2, //X座標は、100 Constraint.Constant(100), // Y座標は、label1の20下(他の要素との相対位置で配置) Constraint.RelativeToView(label1, (parent, sibling) => sibling.Y + sibling.Height + 20) ); MainPage = new ContentPage { Content = relativeLayout }; } }
(5) ContentView / Frame / ScrollView
iOS | Android | WindowsPhone |
コンテンツビュー、フレーム、スクロールビューは、単一の子要素を扱うレイアウトです。 下記のサンプルは、この3つのレイアウトをスタックレイアウトで縦に並べたものです。
public class App : Application { public App() { //フレームの生成 var frame = new Frame { //枠線の効果 OutlineColor = Color.Accent, HasShadow = true, //ラベルを配置する Content = new Label { Text = "Frame" } }; //コンテンツビューの生成 var contentView = new ContentView { BackgroundColor = Color.FromHex("EB6379"), Padding = new Thickness(50), //ContentView内での余白 //ラベルを配置する Content = new Label { Text = "ContentView" ,FontSize=20} }; //スクロールビューの生成 var sb = new StringBuilder(); //100行のテキストを作成 for (var i = 0; i < 100; i++) { sb.Append(string.Format("ScrollView {0}行目\n", i+1)); } var scrollView = new ScrollView { VerticalOptions = LayoutOptions.FillAndExpand, //ラベルを配置する Content = new Label { Text = sb.ToString(), FontSize = 20, TextColor = Color.FromHex("82DADA") } }; MainPage = new ContentPage { //スタックレイアウトをContentに設定 Content = new StackLayout { Spacing = 10, //要素間のスペース Padding = new Thickness(10, Device.OnPlatform(20, 10, 10), 10, 10), //作成した「フレーム」・「コンテンツビュー」・「スクロールビュー」を縦に配置する Children = { frame, contentView, scrollView } } }; } }
3 まとめ
今回は、コントロールを配置する際に、これをサポートするレイアウトについて紹介しました。 レイアウトは、プラットフォームごとの違いが少ないので、比較的違和感が少ないのでは無いでしょうか。
最初に紹介した「ページ」を生成し、そのページ上で今回紹介したのレイアウトが利用できれば、後は色々なコントロールを配置する事でXamarin.Formsの画面が出来上がります。
次回は、各種のコントロールについて紹介したいと思います。
サンプルコード(https://github.com/furuya02/Xamarin.Forms.LayoutSample)
本記事は、2015年10月24日現在で最新の Xamarin.Forms 1.5.1.6471 を使用して作成されています。
4 参考リンク
Xamarin.Forms Layouts
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
Xamarin記事一覧(SAPPOROWORKSの覚書)