AbsoluteLayout
を使うと画像の上にボタンやラベルといったコントロールを重ねることができます。さらに、Xamarin.FormsのAbsoluteLayoutは「LayoutFlags」と「LayoutBounds」を駆使することでとても柔軟なレイアウトが可能となっています。
自分で絶対座標を計算しなくても良いのは素敵ですね。
LayoutFlags と LayoutBounds
LayoutFlags、LayoutBoundsを適切に設定することで親要素(AbsoluteLayout)に対する位置、サイズを比率で指定することができます。
LayoutFlagsは AbsoluteLayoutFlags
列挙型として定義されています。
public enum AbsoluteLayoutFlags
{
None = 0,
XProportional = 1,
YProportional = 2,
WidthProportional = 4,
HeightProportional = 8,
PositionProportional = 3,
SizeProportional = 12,
All = -1
}
AbsoluteLayoutFlags
の指定によって Rectangle
の解釈が変わり、「〜Proportional」に対応する部分は絶対値ではなく、座標やサイズを0〜1の比率で指定したものとして扱われます。例えば、 WidthProportional
が指定されている場合に Rectangle.Width
を 1 に設定すると、子要素の幅は親要素(AbsoluteLayout)に対する100%(親要素の幅と同じ)となります。
Rectangle.Width
、 Rectangle.Height
には絶対値の代わりに AbsoluteLayout.AutoSize
を指定することができます。(XAMLの場合は AutoSize
) これにより、要素の動的なサイズ変化にも対応してくれます。
LayoutFlags、LayoutBoundsの指定はC#で書くとこうなります。
AbsoluteLayout.SetLayoutFlags (
label,
AbsoluteLayoutFlags.PositionProportional
);
AbsoluteLayout.SetLayoutBounds (
label,
new Rectangle (
0.5, // X
0.5, // Y
AbsoluteLayout.AutoSize, // Width
AbsoluteLayout.AutoSize) // Height
);
同じことをXAMLで書くとこうなります。
<Label Text="中心に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5, 0.5, AutoSize, AutoSize"/>
LayoutFlagsの複数指定
AbsoluteLayoutFlags
は組み合わせることができます。例えば、 PositionProportional
を指定するのは XProportional
と YProportional
を同時に指定するのと等しく、 SizeProportional
を指定するのは WidthProportional
と HeightProportional
を同時に指定するのと等しくなります。
C#で書く場合は論理和を使います。
AbsoluteLayout.SetLayoutFlags (
boxView,
AbsoluteLayoutFlags.XProportional |
AbsoluteLayoutFlags.YProportional);
AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAMLで書く場合はカンマ(,)で区切ります。
<BoxView Color="#88D3381C"
AbsoluteLayout.LayoutFlags="XProportional, YProportional"
AbsoluteLayout.LayoutBounds="0.5, 0.5, AutoSize, AutoSize"/>
サンプル:帯状に配置
AbsoluteLayout
の上下左右の領域に配置するサンプル。メニューやキャプションを置く場所として使うイメージ。うまく調整すれば四角いフレームなんかも作れそうですね。
こんな感じ。
上付き
C#
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0.5, 0, 1, 0.25));
XAML
<BoxView Color="#88D3381C"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.25"/>
下付き
C#
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0.5, 1, 1, 0.25));
XAML
<BoxView Color="#88AACF53"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0.5, 1, 1, 0.25"/>
左付き
C#
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0, 0.5, 0.25, 1));
XAML
<BoxView Color="#881E50A2"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0, 0.5, 0.25, 1"/>
右付き
C#
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (1, 0.5, 0.25, 1));
XAML
<BoxView Color="#88EBD842"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="1, 0.5, 0.25, 1"/>
サンプル:隅に配置
AbsoluteLayout
の中央と四隅に配置するサンプル。幅、高さに AbsoluteLayout.AutoSize
を指定することで要素のサイズ変化にも対応してくれます。例えば、右下の要素が大きくなった場合でも画面外にはみ出ることなく、収まるように再配置してくれます。
こんな感じ。
中心に配置
C#
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAML
<Label Text="中心に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5, 0.5, AutoSize, AutoSize"/>
左上に配置
C#
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAML
<Label Text="左上に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0, 0, AutoSize, AutoSize"/>
右上に配置
C#
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds (label, new Rectangle (1, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAML
<Label Text="右上に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="1, 0, AutoSize, AutoSize"/>
右下に配置
C#
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds (label, new Rectangle (1, 1, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAML
<Label Text="右下に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="1, 1, AutoSize, AutoSize"/>
左下に配置
C#
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0, 1, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAML
<Label Text="左下に配置"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0, 1, AutoSize, AutoSize"/>