Layouts
Xamarin.Forms has several layouts and features for organizing content on screen. For a comprehensive guide see the Xamarin Guide to Layouts
Layouts with single content
Layout | Description | Appearance |
---|---|---|
ContentView | contains a single child | ![]() |
Frame | displays a border, or frame, around its single child | ![]() |
ScrollView | capable of scrolling its contents | ![]() |
Layouts with multiple children
Layout | Description | Appearance |
---|---|---|
StackLayout | positions child elements in a stack either horizontally or vertically | ![]() |
Grid | positions its child elements in a grid of rows and columns | ![]() |
AbsoluteLayout | positions child elements at specific locations relative to its parent | ![]() |
RelativeLayout | positions child elements relative to the RelativeLayout itself or to their siblings | ![]() |
FlexLayout | allows children to be stacked or wrapped with many alignment and orientation options. | ![]() |
Content View
A ContentView
contains a single child element and is typically used to create custom, reusable controls.
View.ContentView(
View.Label("content")
)
See also:
Frame
A frame contains other content. A simple Frame
is as follows:
View.Frame(
hasShadow = true,
backgroundColor = Color.Fuchsia,
content = View.Label("I'm framed")
)

See also:
ScrollView
ScrollView contains layouts and enables them to scroll offscreen. ScrollView is also used to allow views to automatically move to the visible portion of the screen when the keyboard is showing.
View.ScrollView(
View.StackLayout([
for i in 1 .. 100 ->
View.Label(text = sprintf "item %i" i)
])
)
The scroll position can be setted programmatically through the attribute scrollTo
. This attribute needs the X and Y coordinates to scroll to and an indication whether it should be animated or not. (Animated
/NotAnimated
)
Note: Fabulous will try to scroll to these coordinates every time it needs to refresh the UI. Making use of the optional argument is recommended.
You can also subscribe to the event Scrolled
to be notified when the scrolling is over.
For more complex scenarios, you can directly use the method from Xamarin.Forms ScrollView.ScrollToAsync(x, y, animated)
This method offers the advantage of being awaitable until the end of the scrolling.
To do this, a reference to the underlying ScrollView is needed.
let scrollViewRef = ViewRef<ScrollView>()
View.ScrollView(ref=scrollViewRef, content=(...))
// Some time later (usually in a Cmd)
let scrollToCoordinates x y animated =
async {
match scrollViewRef.TryValue with
| None ->
return None
| Some scrollView ->
do! scrollView.ScrollToAsync(x, y, animated) |> Async.AwaitTask
return (Some Scrolled)
} |> Cmd.ofAsyncMsgOption

See also:
StackLayout
StackLayout organizes views in a one-dimensional line (“stack”), either horizontally or vertically. Views in a StackLayout can be sized based on the space in the layout using layout options. Positioning is determined by the order views were added to the layout and the layout options of the views.
View.StackLayout(children = [
View.Label("first label")
View.Button(text = "first button")
View.Label("second label")
])

See also:
Grid
Grid supports arranging views into rows and columns. Rows and columns can be set to have proportional sizes or absolute sizes. The Grid layout should not be confused with traditional tables and is not intended to present tabular data. Grid does not have the concept of row, column or cell formatting. Unlike HTML tables, Grid is purely intended for laying out content.
An example Grid
is as follows:
View.Grid(
rowdefs = [
Dimension.Auto // first row = .Row(0)
Dimension.Absolute 150. // second row = .Row(1)
Dimension.Auto // third row = .Row(2)
Dimension.Star // fourth row = .Row(3)
],
coldefs = [
Dimension.Absolute 200. // first column = .Column(0)
Dimension.Star // second column = .Column(1)
],
children = [
View.Label(text = "first row", backgroundColor = Color.Red).Row(0)
View.Label(text = "second row", backgroundColor = Color.Blue).Row(1)
View.Label(text = "first column", backgroundColor = Color.Yellow).Row(2).Column(0)
View.Label(text = "second column", backgroundColor = Color.Green).Row(2).Column(1)
View.Label(text = "column spanning", backgroundColor = Color.Orange).Row(3).ColumnSpan(2)
]
)

See also:
AbsoluteLayout
AbsoluteLayout positions and sizes child elements proportional to its own size and position or by absolute values. Child views may be positioned and sized using proportional values or static values, and proportional and static values can be mixed.
View.AbsoluteLayout(
backgroundColor = Color.Blue.WithLuminosity(0.9),
children = [
View.Label(text = "Top Left", textColor = Color.Black)
.LayoutFlags(AbsoluteLayoutFlags.PositionProportional)
.LayoutBounds(Rectangle(0.0, 0.0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize))
View.Label(text = "Centered", textColor = Color.Black)
.LayoutFlags(AbsoluteLayoutFlags.PositionProportional)
.LayoutBounds(Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize))
View.Label(text = "Bottom Right", textColor = Color.Black)
.LayoutFlags(AbsoluteLayoutFlags.PositionProportional)
.LayoutBounds(Rectangle(1.0, 1.0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize))
]
)

See also:
RelativeLayout
RelativeLayout is used to position and size views relative to properties of the layout or sibling views. Unlike AbsoluteLayout, RelativeLayout does not have the concept of the moving anchor and does not have facilities for positioning elements relative to the bottom or right edges of the layout. RelativeLayout does support positioning elements outside of its own bounds.
An example RelativeLayout
is as follows:
View.RelativeLayout([
View.Label(text = "RelativeLayout Example", textColor = Color.Red)
.XConstraint(Constraint.RelativeToParent(fun parent -> 0.0))
View.Label(text = "Positioned relative to my parent", textColor = Color.Red)
.XConstraint(Constraint.RelativeToParent(fun parent -> parent.Width / 3.0))
.YConstraint(Constraint.RelativeToParent(fun parent -> parent.Height / 2.0))
])
See also:
FlexLayout
FlexLayout is similar to the Xamarin.Forms StackLayout in that it can arrange its children horizontally and vertically in a stack. However, the FlexLayout is also capable of wrapping its children if there are too many to fit in a single row or column, and also has many options for orientation, alignment, and adapting to various screen sizes.
View.FlexLayout(
direction = FlexDirection.Column,
children = [
View.Label(text = "Seated Monkey", fontSize = FontSize.fromNamedSize NamedSize.Large, textColor=Color.Blue)
View.Label(text = "This monkey is laid back and relaxed.")
View.Label(text = " - Often smiles mysteriously")
View.Label(text = " - Sleeps sitting up")
View.Image(
source = Image.ImagePath "images/160px-Vervet_monkey_Krugersdorp_game_reserve_%285657678441%29.jpg"
).Order(-1).AlignSelf(FlexAlignSelf.Center)
View.Label(margin = Thickness(0.0, 4.0)).Grow(1.0)
View.Button(text = "Learn More", fontSize = FontSize.fromNamedSize NamedSize.Large, cornerRadius = 20)
]
)

See also: