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
を同時に指定するのと等しくなります。
AbsoluteLayout.SetLayoutFlags ( label, AbsoluteLayoutFlags.XProportional | AbsoluteLayoutFlags.YProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
XAMLで書く場合はカンマ(,)で区切ります。
<Label Text="中心に配置" AbsoluteLayout.LayoutFlags="XProportional, YProportional" AbsoluteLayout.LayoutBounds="0.5, 0.5, AutoSize, AutoSize"/>
サンプル:帯状に配置
AbsoluteLayout
の上下左右の領域に配置するサンプル。メニューやキャプションを置く場所として使うイメージ。うまく調整すれば四角いフレームなんかも作れそうですね。
こんな感じ。
上付き
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0.5, 0, 1, 0.25));
<BoxView Color="#88D3381C" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.25"/>
下付き
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0.5, 1, 1, 0.25));
<BoxView Color="#88AACF53" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0.5, 1, 1, 0.25"/>
左付き
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (0, 0.5, 0.25, 1));
<BoxView Color="#881E50A2" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0, 0.5, 0.25, 1"/>
右付き
AbsoluteLayout.SetLayoutFlags (boxView, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutBounds (boxView, new Rectangle (1, 0.5, 0.25, 1));
<BoxView Color="#88EBD842" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1, 0.5, 0.25, 1"/>
サンプル:隅に配置
AbsoluteLayout
の中央と四隅に配置するサンプル。幅、高さに AbsoluteLayout.AutoSize
を指定することで要素のサイズ変化にも対応してくれます。例えば、右下の要素が大きくなった場合でも画面外にはみ出ることなく、収まるように再配置してくれます。
こんな感じ。
中心に配置
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
<Label Text="中心に配置" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5, 0.5, AutoSize, AutoSize"/>
左上に配置
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
<Label Text="左上に配置" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0, 0, AutoSize, AutoSize"/>
右上に配置
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (1, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
<Label Text="右上に配置" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="1, 0, AutoSize, AutoSize"/>
右下に配置
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (1, 1, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
<Label Text="右下に配置" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="1, 1, AutoSize, AutoSize"/>
左下に配置
AbsoluteLayout.SetLayoutFlags (label, AbsoluteLayoutFlags.PositionProportional); AbsoluteLayout.SetLayoutBounds (label, new Rectangle (0, 1, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
<Label Text="左下に配置" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0, 1, AutoSize, AutoSize"/>