Xamarin.Formsで、RelativeLayoutコントロールと各種のプロパティを使用して、画面のサイズなどに相対的にコントロールを配置する方法を解説する。
対象:Visual Studio 2015以降
Xamarin.FormsでUIコントロールを配置するとき、RelativeLayoutコントロール(Xamarin.Forms名前空間)を使えば位置やサイズを相対的に指定できる。
本稿では、RelativeLayoutコントロールを使う記述方法と、動的に位置やサイズを変更する方法を解説する*1。
*1 本稿で使用したXamarin.Formsのバージョン
Xamarin 4.2.1.60 (47830f6)/Xamarin.Forms 2.2.0.45
RelativeLayoutコントロールを使うと、異なる画面サイズに対して柔軟に変化するレイアウトを実現できる。次の画像は、同じ画面をサイズを変えて2つ並べたものだ。緑・赤・青色のコントロールの位置やサイズが、画面サイズに応じて変化しているのが分かるだろう。
配置したいUIコントロールに、位置/サイズのconstraint(制約)を指定する。constraintには、WidthConstraint添付プロパティ(幅)/HeightConstraint添付プロパティ(高さ)/XConstraint添付プロパティ(横位置)/YConstraint添付プロパティ(縦位置)の4つがある。
constraintには、次の表に示すパラメータを指定する。
パラメータ名 | 意味 | 例 |
---|---|---|
Type | 相対指定の基準にするコントロールのタイプ。親コントロールか他のコントロールか | RelativeToParent(親コントロール) RelativeToView(他のコントロール) |
ElementName | Type=RelativeToViewのとき、相対指定の基準にするコントロールを名前で指定する(Type=RelativeToParentのときは指定しない) | Label1 Button2 |
Property | 相対指定の基準にするコントロールのプロパティ | Height X |
Factor | Propertyパラメータで指定したプロパティの値に掛ける数値(省略時は1.0) | 1.0 0.15 |
Constant | Factorパラメータを掛けた後に加算する数値(省略時は0.0) | 2.5 -50 |
実際の例として、冒頭に掲げた画面のXAMLコードを示す(次のコード)。
<RelativeLayout x:Name="RelativeLayout1" BackgroundColor="Silver">
<!-- 親(RelativeLayoutコントロール)に対する相対指定 -->
<Label x:Name="Label1" BackgroundColor="Green" TextColor="White"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width, Factor=0.5}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Height, Factor=0.15}"
RelativeLayout.XConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=X, Constant=20}"
RelativeLayout.YConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Y, Constant=50}"
Text="親に対して、幅50%・高さ15%、位置(20,50)" />
<!-- Label1(緑色)に対する相対指定 -->
<Label BackgroundColor="Maroon" TextColor="White"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=Label1,
Property=Width, Factor=1}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=Label1,
Property=Height, Factor=2}"
RelativeLayout.XConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=Label1,
Property=Width, Factor=0.5, Constant=20}"
RelativeLayout.YConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=Label1,
Property=Height, Constant=50}"
Text="緑に対して、幅100%・高さ200%、相対位置(幅の半分,下端)" />
<!-- 親(RelativeLayoutコントロール)に対する相対指定 -->
<Label x:Name="Label3" BackgroundColor="Blue" TextColor="White"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width, Factor=1}"
HeightRequest="50"
RelativeLayout.XConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Height, Constant=-50}"
Text="親に対して、幅100%・高さ50epx、位置(0,下端-50)" />
</RelativeLayout>
RelativeLayoutコントロール内に配置したUIコントロールの位置やサイズは、後から動的に変更できる。それには、RelativeLayoutクラスのSetBoundsConstraintメソッドを使う。
例えば、上述の画面で下端にある青いラベル(=Label3)の位置を、画面が横長のときに右端へ移動させるには、コードビハインドのSizeChangedイベントハンドラーを次のコードのように記述する。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.SizeChanged += MainPage_SizeChanged; // イベントハンドラーを接続
}
// 追加したイベントハンドラー
private void MainPage_SizeChanged(object sender, EventArgs e)
{
if (Width > Height)
{
// 横長:Label3を右端に
RelativeLayout.SetBoundsConstraint(Label3,
BoundsConstraint.FromExpression(
() => new Rectangle(
RelativeLayout1.Width - 125.0,
RelativeLayout1.Y,
125.0,
RelativeLayout1.Height),
null));
Label3.Text = "親に対して、幅125epx・高さ100%、位置(右端-125,0)";
}
else
{
// 縦長:Label3を下端に(XAML記述の繰り返し)
RelativeLayout.SetBoundsConstraint(Label3,
BoundsConstraint.FromExpression(
() => new Rectangle(
RelativeLayout1.X,
RelativeLayout1.Height - 50.0,
RelativeLayout1.Width,
50.0),
null));
Label3.Text = "親に対して、幅100%・高さ50epx、位置(0,下端-50)";
}
}
}
以上で完成だ。実行してみると次からの画像のようになる。まず、縦長の画面の場合。
そして、次が画面を横長にした場合だ。
RelativeLayoutコントロールは、その中に配置するUIコントロールの位置やサイズを相対的に指定する。また、コードビハインドで後から動的に位置やサイズを変更できる。
利用可能バージョン:Visual Studio 2015以降
カテゴリ:Xamarin 処理対象:Xamarin.Forms
関連TIPS:Xamarin.Forms:コントロールを等間隔に配置するには?
関連TIPS:Xamarin.Forms:Gridコントロールを分割するには?
Copyright© Digital Advantage Corp. All Rights Reserved.