[Xamarin][筆記]Layout機制

  • 1745
  • 0

筆記Xamarin官網上有關Layout的資訊

Xamarin.Form使用幾種不同的Layout來組織管理View物件在畫面上的位置以及尺寸大小。

View物件的位置受到許多因素的影響,parent layout的種類會先限制View物件的排列方式,LayoutOptions的Alignment接著影響在layout物件中的相對位置。

LayoutOptions

LayoutOptions定義了Alignment,也就是Start, Center, End, Fill這幾種排列方式。

<StackLayout Margin="0,20,0,0">
  ...
  <Label Text="Start" BackgroundColor="Gray" HorizontalOptions="Start" />
  <Label Text="Center" BackgroundColor="Gray" HorizontalOptions="Center" />
  <Label Text="End" BackgroundColor="Gray" HorizontalOptions="End" />
  <Label Text="Fill" BackgroundColor="Gray" HorizontalOptions="Fill" />
</StackLayout>

如果View物件是在StackLayout中,則可以設定StartAndExpand, CenterAndExpand, EndAndExpand, FillAndExpand 這幾種Expansion 方式。 如果View物件有設定這幾種方式,StackLayout會自動的均分View物件的間距及高度(space)。

<StackLayout Margin="0,20,0,0">
  ...
  <BoxView BackgroundColor="Red" HeightRequest="1" />
  <Label Text="Start" BackgroundColor="Gray" VerticalOptions="StartAndExpand" />
  <BoxView BackgroundColor="Red" HeightRequest="1" />
  <Label Text="Center" BackgroundColor="Gray" VerticalOptions="CenterAndExpand" />
  <BoxView BackgroundColor="Red" HeightRequest="1" />
  <Label Text="End" BackgroundColor="Gray" VerticalOptions="EndAndExpand" />
  <BoxView BackgroundColor="Red" HeightRequest="1" />
  <Label Text="Fill" BackgroundColor="Gray" VerticalOptions="FillAndExpand" />
  <BoxView BackgroundColor="Red" HeightRequest="1" />
</StackLayout>

StackLayout

StackLayout可以由上到下或由左到右的排列子View物件,他的排列方式最簡單也最單純,所以也常用來排列其他的Layout物件。

View物件的Size

預設在StackLayout中的UI物件會間隔6px的距離,可以透過StackLayout的Spacing屬性進行修改。

<StackLayout Spacing="10" x:Name="layout">
...
</StackLayout>

如果調整了Spacing,StackLayout也會跟著調整分派給子View物件的space,進而可能影響到View物件的大小。

如果View物件想要維持固定的大小,可以設定HeightRequest屬性

<BoxView HeightRequest="75" Color="Blue" VerticalOptions="End"
        HorizontalOptions="FillAndExpand" />

詳細設定可參考-StackLayout

AbsoluteLayout

在AbsoluteLayout中可以明確地指派子View物件的位置和大小,透過設定LayoutBounds以設定以下四個值: X, Y, Width, HeightX, Y是設定子View物件的anchor的座標位置以決定位置,Width, Height則分別設定其長度及寬度以決定大小。

上述的值的設定,可以是一個實際數值,也可以是一個比例值,比例值是由0到1之間的double值。這兩者可以混用,也因此需要設定AbsoluteLayoutFlag以定義那些數值是實際數值還是比例值

<AbsoluteLayout>
	<Label Text="I'm bottom center on every device." AbsoluteLayout.LayoutBounds=".5,1,.5,.1" AbsoluteLayout.LayoutFlags="All" LineBreakMode="WordWrap"  />

	<BoxView Color="Blue" AbsoluteLayout.LayoutBounds=".5,0,100,25" AbsoluteLayout.LayoutFlags="PositionProportional" />
</AbsoluteLayout>

詳細設定可參考-AbsoluteLayout

RelativeLayout

RelativeLayout的排列方式允許子View物件依據Layout物件或是同一層的View物件進行相對位置及大小的設定。他的設定方式比較繁雜,是透過ConstraintExpressions提供以下五個資訊

  • Type – 設定RelativeToParent(相對於Parent物件) 或 RelativeToView(相對於其他View物件)
  • Property – 被比對的物件的某個屬性,用來作為運算的basis
  • Factor – Property的倍數
  • Constant – 作為運算用的offset
  • ElementName – RelativeToView時指定的View物件

看Code可以比較了解參數的意義

<BoxView Color="Green" WidthRequest="50"  HeightRequest="50" 
    RelativeLayout.XConstraint = "{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.5,Constant=-100}" 
    RelativeLayout.YConstraint ="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.5,Constant=-100}"/>

可以對應成以下的程式碼

layout.Children.Add(box, Constraint.RelativeToParent((parent) =>
    {
      return (.5 * parent.Width) - 100;
    }),
    Constraint.RelativeToParent((parent) =>
    {
        return (.5 * parent.Height) - 100;
    }),
    Constraint.Constant(50), Constraint.Constant(50));

詳細設定可參考-RelativeLayout

Grid

Grid可以使用Row及Column顯示物件,概念跟Table類似,但還是有些差異。Grid是以RowDefinitions以及ColumnDefinitions定義行列的數量及寬高。寬高的設定有以下三種方式:

  • Auto: 自動依據內涵物件調整寬高
  • Proportional(*): 將剩餘的空間依據比例值調整寬高
  • Absolute: 寬高指定某個特定值

使用範例

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="2*" />
    <RowDefinition Height="*" />
    <RowDefinition Height="200" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
</Grid>

Spacing

Grid可以透過以下的屬性定義Row與Columns之間的間距

  • ColumnSpacing
  • RowSpacing
<Grid ColumnSpacing="5">
  <Grid.ColumnDefinitions>
    <ColumnDefinitions Width="*" />
    <ColumnDefinitions Width="*" />
  </Grid.ColumnDefinitions>
</Grid>

Spans

Grid也可以像Table一樣,設定跨欄及跨列

以下的例子是Button跨兩欄顯示

<Button Text = "0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" />

詳細設定可參考-Grid

ScrollView

可以透過Scrollbar用來顯示比螢幕大的內容

<ContentPage.Content>
    <ScrollView>
        <StackLayout>
            <BoxView BackgroundColor="Red" HeightRequest="600" WidthRequest="150" />
            <Entry />
        </StackLayout>
    </ScrollView>
</ContentPage.Content>

以上述的例子來看,當使用者透過Entry物件來輸入資訊時,對自動scroll讓輸入框可以顯示在螢幕上。

Properties

ScrollView有以下幾個Properties

  • Content - ScrollView中的view物件
  • ContentSize - 取得content的size
  • Orientation - Scroll的方向
  • ScrollX - 目前的X diemension
  • ScrollY - 目前的Y diemension

Methods

ScrollView提供了ScrollToAsync method,可以移到特定的位置,或是某一個View物件

當要移動到某一個View物件時,有以下幾個選項可選

  • Center
  • End
  • MakeVisible
  • Start

Events

ScrollView提供一個event - Scrolled,Scroll之後就會觸發

Label label = new Label { Text = "Position: " };
ScrollView scroll = new ScrollView();
scroll.Scrolled += (object sender, ScrolledEventArgs e) => {
    label.Text = "Position: " + e.ScrollX + " x " + e.ScrollY;
};

詳細設定可參考-ScrollView