22
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Xamarin.Forms] AbsoluteLayoutでプロポーショナルレイアウト

Last updated at Posted at 2015-09-24

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.WidthRectangle.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 を指定するのは XProportionalYProportional を同時に指定するのと等しく、 SizeProportional を指定するのは WidthProportionalHeightProportional を同時に指定するのと等しくなります。

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 の上下左右の領域に配置するサンプル。メニューやキャプションを置く場所として使うイメージ。うまく調整すれば四角いフレームなんかも作れそうですね。

こんな感じ。

スクリーンショット 2015-09-24 13.35.14.jpg

上付き

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 を指定することで要素のサイズ変化にも対応してくれます。例えば、右下の要素が大きくなった場合でも画面外にはみ出ることなく、収まるように再配置してくれます。

こんな感じ。

スクリーンショット 2015-09-24 11.16.00.jpg

中心に配置

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"/>

参考

Xamarin.Forms AbsoluteLayout Recipe

Demystifying Xamarin Forms AbsoluteLayout and RelativeLayout positioning. | Adventures in Xamarin Forms

22
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?