แชร์ผ่าน


Summary of Chapter 4. Scrolling the stack

Note

This book was published in the spring of 2016, and has not been updated since then. There is much in the book that remains valuable, but some of the material is outdated, and some topics are no longer entirely correct or complete.

This chapter is primarily devoted to introducing the concept of layout, which is the overall term for the classes and techniques that Xamarin.Forms uses to organize the visual display of multiple views on the page.

Layout involves several classes that derive from Layout and Layout<T>. This chapter focuses on StackLayout.

Note

The FlexLayout introduced in Xamarin.Forms 3.0 can be used in ways that are similar to StackLayout but with more flexibility.

Also introduced in this chapter are the ScrollView, Frame, and BoxView classes.

Stacks of views

StackLayout derives from Layout<View> and inherits a Children property of type IList<View>. You add multiple view items to this collection, and StackLayout displays them in a horizontal or vertical stack.

Set the Orientation property of StackLayout to a member of the StackOrientation enumeration, either Vertical or Horizontal. The default is Vertical.

Set the Spacing property of StackLayout to a double value to specify a spacing between the children. The default value is 6.

In code, you can add items to the Children collection of StackLayout in a for or foreach loop as demonstrated in the ColorLoop sample, or you can initialize the Children collection with a list of the individual views as demonstrated in ColorList. The children must derive from View but can include other StackLayout objects.

Scrolling content

If a StackLayout contains too many children to display on a page, you can put the StackLayout in a ScrollView to allow scrolling.

Set the Content property of ScrollView to the view you want to scroll. This is often a StackLayout, but it can be any view.

Set the Orientation property of ScrollView to a member of the ScrollOrientation property, Vertical, Horizontal, or Both. The default is Vertical. If the content of a ScrollView is a StackLayout, the two orientations should be consistent.

The ReflectedColors sample demonstrates the use of ScrollView and StackLayout to display the available colors. The sample also demonstrates how to use .NET reflection to obtain all the public static properties and fields of the Color structure without the need to explicitly list them.

The Expands option

When a StackLayout stacks its children, each child occupies a particular slot within the total height of the StackLayout that depends on the child's size and the settings of its HorizontalOptions and VerticalOptions properties. These properties are assigned values of type LayoutOptions.

The LayoutOptions structure defines two properties:

For your convenience, the LayoutOptions structure also defines eight static read-only fields of type LayoutOptions that encompass all combinations of the two instance properties:

The following discussion involves a StackLayout with a default vertical orientation. The horizontal StackLayout is analogous.

For a vertical StackLayout, the HorizontalOptions setting determines how a child is horizontally positioned within the width of the StackLayout. An Alignment setting of Start, Center, or End causes the child to be horizontally unconstrained. The child determines its own width and is positioned at the left, center, or right of the StackLayout. The Fill option causes the child to be horizontally constrained and fills the width of the StackLayout.

For a vertical StackLayout, each child is vertically unconstrained and gets a vertical slot depending on the child's height, in which case the VerticalOptions setting is irrelevant.

If the vertical StackLayout itself is unconstrained—that is if its VerticalOptions setting is Start, Center, or End, then the height of the StackLayout is the total height of its children.

However, if the vertical StackLayout is vertically constrained—if its VerticalOptions setting is Fill—then the height of the StackLayout will be the height of its container, which might be greater than the total height of its children. If that is the case, and if at least one child has a VerticalOptions setting with an Expands flag of true, then the extra space in the StackLayout is allocated equally among all those children with an Expands flag of true. The total height of the children will then equal the height of the StackLayout, and the Alignment part of the VerticalOptions setting determines how the child is vertically positioned in its slot.

This is demonstrated in the VerticalOptionsDemo sample.

Frame and BoxView

These two rectangular views are often used for presentation purposes.

The Frame view displays a rectangular frame around another view, which can be a layout such as StackLayout. Frame inherits a Content property from ContentView that you set to the view to be displayed within the Frame. The Frame is transparent by default. Set the following three properties to customize the frame's appearance:

  • The OutlineColor property to make it visible. It is common to set OutlineColor to Color.Accent when you don't know the underlying color scheme.
  • The HasShadow property can be set to true to display a black shadow on iOS devices.
  • Set the Padding property to a Thickness value to leave a space between the frame and the frame's content. The default value is 20 units on all sides.

The Frame has default HorizontalOptions and VerticalOptions values of LayoutOptions.Fill, which means that the Frame will fill its container. With other settings, the size of the Frame is based on the size of its content.

The Frame is demonstrated in the FramedText sample.

The BoxView displays a rectangular area of color specified by its Color property.

If the BoxView is constrained (its HorizontalOptions and VerticalOptions properties have their default settings of LayoutOptions.Fill), the BoxView fills the space available for it. If the BoxView is unconstrained (with HorizontalOptions and LayoutOptions settings of Start, Center, or End), it has a default dimension of 40 units square. A BoxView can be constrained in one dimension and unconstrained in the other.

Often, you'll set the WidthRequest and HeightRequest properties of BoxView to give it a specific size. This is illustrated by the SizedBoxView sample.

You can use several instances of StackLayout to combine a BoxView and several Label instances in a Frame to display a particular color, and then put each of these views in a StackLayout in a ScrollView to create the attractive list of colors shown in the ColorBlocks sample:

Triple screenshot of color blocks

A ScrollView in a StackLayout?

Putting a StackLayout in a ScrollView is common, but putting a ScrollView in a StackLayout is also sometimes convenient. In theory, this shouldn't be possible because the children of a vertical StackLayout are vertically unconstrained. But a ScrollView must be vertically constrained. It must be given a specific height so that it can then determine the size of its child for scrolling.

The trick is to give the ScrollView child of the StackLayout a VerticalOptions setting of FillAndExpand. This is demonstrated in the BlackCat sample.

The BlackCat sample also demonstrates how to define and access program resources that are embedded in the shared library. This can also be achieved with Shared Asset Projects (SAPs) but the process is a little trickier, as the BlackCatSap sample demonstrates.