APL GridSequence (APL 1.6)

(This is not the most recent version of APL. Use the Other Versions option to see the documentation for the most recent version of APL)

The GridSequence component uses a data set to display a repeating set of components in a fixed grid layout that scrolls in a single direction.

The difference between a GridSequence and a Container component is that the GridSequence has better performance on long lists, but a less flexible layout model. The difference between a GridSequence and a regular Sequence is that the GridSequence arranges its children in rows and columns.

For a pre-built responsive template that displays a GridSequence, see AlexaGridList.

Properties

The GridSequence component has the following properties:

Property Type Default Styled Dynamic Description

childHeight, childHeights

Dimension or array of dimension

Required

No

Yes

The height of children

childWidth, childWidths

Dimension or array of dimension

Required

No

Yes

The width of children

numbered

Boolean

false

No

No

When true, assign ordinal numbers to the GridSequence children in the data-binding context.

onScroll

Array of command

[]

No

No

Commands to run during scrolling.

preserve

Array of string

[]

No

No

Properties to save when reinflating the document with the Reinflate command.

scrollDirection

One of: horizontal, vertical

vertical

No

No

The direction to scroll this GridSequence.

snap

One of: none, start, center, end, forceStart, forceCenter, forceEnd

none

Yes

No

The alignment that the child components snap to when scrolling stops.

height and width

To minimize visibility errors, the height of a vertical GridSequence and the width of a horizontal GridSequence initialize to 100 dp when not specified. Don't use auto for the height or width. Use an absolute or relative dimension for the GridSequence size.

childHeight

An array that determines the height of each row in the GridSequence.

A vertically-scrolling GridSequence uses the first value in childHeight and this value must be either an absolute or a relative dimension. The childHeight can't be auto.

For a horizontally-scrolling GridSequence, you can specify one or more childHeight values. The layout algorithm described in Calculating the height and width of columns and rows positions each child item.

childWidth

An array that determines the width of each column in the GridSequence.

A horizontally-scrolling GridSequence uses the first value in childWidth and this value must be either an absolute or a relative dimension. The childWidth can't be auto.

For a vertically-scrolling GridSequence, you can specify one or more childWidth values. The layout algorithm described in Calculating the height and width of columns and rows positions each child item.

numbered

When true, set the data-binding ordinal for each of the items in the GridSequence. The ordinals start with "1" and increment by one unless the numbering property in a child is skip or reset. The firstItem and lastItem aren't included in ordinal numbering.

The numbered property doesn't display any numbers on the screen automatically. You can use the ordinal value in the data-binding context to display the numbers in a Text component.

onScroll

Commands to run during scrolling. The runtime attempts to run these commands one time per drawing frame during scrolling, but this attempt might not succeed. On slow hardware, the onScroll command might run intermittently.

The event.source.position reported in the command is the percentage of the current scroll position as expressed by the width/height of the GridSequence. For example, assume the GridSequence is 200 pixels wide and the contents have shifted left by 520 pixels. The event.source.position value is 2.60.

The event generated has the form:

"event": {
  "source": {
    "type": "GridSequence",
    "handler": "Scroll",
    ...                     // Component source properties
  }
}

Refer to Event source for a description of event.source properties.

The onScroll event handler runs in fast mode.

preserve

An array of dynamic component properties and bound properties to save when reinflating the document with the Reinflate command.

A GridSequence has the following component-specific property names you can assign to the preserve array:

  • centerId – The id of the child in the center of the sequence.
  • centerIndex – The index of the child in the center of the sequence.
  • firstId – The id of the child at the top of the sequence.
  • firstIndex – The index of the child at the top of the sequence.
  • scrollOffset – Absolute scroll position (measured in dp).
  • scrollPercent – Relative scroll position (measured as percentage of the visible area).

The firstIndex option uses the index of the current child shown at the start of the sequence and (after reinflation) sets the scroll position to place the same child (by index) at the start of the sequence. The firstId uses the id of the current child shown at the start of the sequence and (after reinflation) sets the scroll position to put the same child (by id) at the start of the sequence.

The centerIndex option uses the index of the current child shown in the center of the sequence and (after reinflation) sets the scroll position to place the same child (by index) in the center of the sequence. The centerId uses the id of the current child shown in the center of the sequence and (after reinflation) sets the scroll position to put the same child (by id) in the center of the sequence.

When searching by id (for both centerId and firstId), if the id is not found either before reinflation or after reinflation, the sequence is positioned at the start. When searching for a component by index (for both centerIndex and firstIndex), if no child is present at that index, the sequence is positioned at the start.

scrollDirection

The scrollDirection is either vertical or horizontal.

snap

The alignment that the child components snap to when scrolling stops. When the user scrolls through the content and then stops scrolling, the GridSequence can shift the child items to "snap" to the start, center, or end of the GridSequence container. The GridSequence aligns the child item closest to the snap position. For example, when snap is center, the GridSequence shifts the items so that the item closest to the center snaps to the center of the container.

A GridSequence supports two types of snap behavior:

  • Snap when scrolling has velocity – When the user scrolls through the content, releases the pointer, and allows the sequence to slow to a stop, the GridSequence aligns the child components as requested or at the start or end of the sequence. No snapping occurs when the user releases the pointer with little or no scroll velocity. For this type of snapping, set snap to start, center, or end.
  • Always snap (force snap) – After the user releases the pointer, the GridSequence always aligns the child components as requested or at the start or end of the GridSequence. With the force snap behavior, the scroll velocity doesn't matter. For this type of snapping, set snap to forceStart, forceCenter, or forceEnd.

Snapping excludes any padding when determining the start, center, or end of the GridSequence container.

The snap property can take the following values:

  • none – (Default) No snapping occurs.
  • start – Align the starting side of the child component to the start of the container when scrolling has velocity.
  • center – Align the center of the child component to the center of the container when scrolling has velocity.
  • end – Align the ending side of the child component to the end of the container when scrolling has velocity.
  • forceStart – Align the starting side of the child component to the start of the container, regardless of scrolling velocity.
  • forceCenter – Align the center of the child component to the center of the container, regardless of scrolling velocity.
  • forceEnd – Align the ending side of the child component to the end of the container, regardless of scrolling velocity.

The snap property applies when the user scrolls the content. The property doesn't apply to scrolling commands. To align items during command-driven scrolling, use the ScrollToComponent or ScrollToIndex command and set the align property on the command.

Multichild properties

A GridSequence is a multichild component. The GridSequence inherits all the multichild properties.

Actionable properties

A GridSequence is an actionable component. The GridSequence inherits all the actionable properties.

GridSequence child items

The children of a GridSequence display in fixed sizes based on the child width, height, and scrolling direction.

The children of a GridSequence support the following additional properties.

Property Type Default Styled Dynamic Description

numbering

One of: normal, skip, or reset

normal

No

No

Control ordinal numbering of the next child.

numbering

Applies when the numbered property for the GridSequence is true. Controls how the GridSequence updates the ordinal value for the next child in the GridSequence.

  • normal: The next child ordinal is ordinal + 1.
  • skip: The next child ordinal is ordinal
  • reset: The next child ordinal is 1

GridSequence and dynamic data sources

You can bind a GridSequence to a dynamic data source, such as a dynamicIndexList. Adding items to the front or middle of a dynamic data source can cause unpredictable scrolling behavior for the GridSequence. To avoid this problem, make sure that the number of items you prepend or add in the middle is a multiple of the number of items in the cross-axis. For a GridSequence with scrollDirection set to vertical, the cross-axis is determined by childWidth. Conversely, for a GridSequence with scrollDirection set to horizontal, the cross-axis is determined by childHeight.

Calculating the height and width of columns and rows

A vertically-scrolling GridSequence uses the following algorithm to calculate the width of columns.

Fixed GridSequenceWidth + Single ChildWidth

When GridSequence width is a known dimension and childWidth has a single value, then the number of columns created equals 100% divided by the childWidth and rounded down.

For example, a child width of "23%" creates 4 columns with a little space left over on the right side. Similarly, a GridSequence with a width of 300 dp and a childWidth of 50 dp produces 6 columns of children.

Fixed GridSequenceWidth + Multiple ChildWidths

When the GridSequence width is a known dimension and childWidth has multiple values, the GridSequence uses the following rules:

  • Columns with an absolute dimension use the assigned value.
  • Columns with a relative dimension (a percentage) use the width of GridSequence multiplied by that percentage.
  • If there is any space left over, divide that space evenly between each column that has an auto dimension. If there is no space left over, the auto columns each have a width of zero.

Auto GridSequenceWidth

When the width of the GridSequence is auto, the GridSequence uses the following rules:

  • Columns with an absolute dimension use the assigned value.
  • Columns with a relative dimension use a width of zero.
  • Columns with an auto dimension use a width of zero.
  • The overall width of the GridSequence is the sum of the widths of the columns.

The algorithm for assigning heights of rows in a horizontally-scrolling GridSequence follows the same rules, using childHeight instead of childWidth.

The GridSequence clips the child items if the child items are larger than the GridSequence. For example, a childWidth array of [ auto, 30%, 50%, 30%, auto ] clips the fourth element and assigns a size of zero to the first and the fifth elements.

Use auto for the childWidth to fill out sizes. To define three equal-sized children, the expression [auto, auto, auto] avoids numerical rounding errors and ensures that the children are the same size.

GridSequence event object

When the GridSequence is the source or target of an event, the following values are reported in event.source or event.target:

{
  // Grid Sequence-specific values
  "type": "GridSequence",
  "position": Number,       // Scrolled position of the component, as a percentage
  "itemsPerCourse": Number, // Number of children in each row (vertical scroll) or column (horizontal scroll)

  // Visible children
  "firstVisibleChild": Integer,       // Index of the first partially visible child
  "firstFullyVisibleChild": Integer,  // Index of the first fully visible child
  "lastFullyVisibleChild": Integer,   // Index of the last fully visible child
  "lastVisibleChild": Integer,        // Index of the last partially visible child

  // General component values
  "bind": Map,              // Access to component data-binding context
  "checked": Boolean,       // Checked state
  "disabled": Boolean,      // Disabled state
  "focused": Boolean,       // Focused state
  "height": Number,         // Height of the component, in dp (includes the padding)
  "id": ID,                 // ID of the component
  "opacity": Number,        // Opacity of the component [0-1]
  "pressed": Boolean,       // Pressed state
  "uid": UID,               // Runtime-generated unique ID of the component
  "width": Number           // Width of the component, in dp (includes the padding)
}

The position value reported is the percentage of the current scroll position as expressed by the width or height of the sequence. This value is the same as the position reported by the onScroll handler.

The event properties include ranges for visible children.

A child component is fully visible when all the following are true:

  • The bounds of the child component don't extend outside of the bounds of the GridSequence,
  • The child component display property is "normal"
  • The child component has an opacity of 1.0.

A child component is visible, but not fully visible when all the following are true:

  • The bounds of child component intersect with the bounds of the GridSequence
  • The child display property is "normal"
  • The child has a non-zero opacity.

The range firstVisibleChild to lastVisibleChild contains all the child components which have some part shown in the sequence. The range firstFullyVisibleChild to lastFullyVisibleChild contains all the child components which are fully visible in the sequence.

The firstVisibleChild and lastVisibleChild properties return –1 if no children are visible in the sequence. The firstFullyVisibleChild and lastFullyVisibleChild properties return –1 if no children are fully visible in the sequence.

The visibility calculations don't consider the child transform property or occlusion by other components that might overlap the sequence.

GridSequence examples

Horizontal grid example

An example of a horizontal grid with two rows of uniform height:

{
  "type": "GridSequence",
  "height": "300dp",
  "scrollDirection": "horizontal",
  "childWidth": "200dp",
  "childHeight": "50%"
}

Because this example is a horizontal scrolling grid, the children display in vertical columns. The height of the GridSequence is 300 dp and the childHeight is 50%. The GridSequence therefore fills two rows of child items. Each row has a height of 150 dp.

Each column is 200 dp wide, as specified by the childWidth. The GridSequence arranges the children from the top-left and fills each column before moving on to the next column. The following figure shows the layout:

Children positioned in horizontally-scrolling grid with equal-sized row heights
Children positioned in horizontally-scrolling grid with equal-sized row heights

Vertical grid example

An example of a vertical grid with three columns of unequal width:

{
  "type": "GridSequence",
  "width": "1000dp",
  "scrollDirection": "vertical",
  "childWidths": [ "20%", "30%", "auto" ],
  "childHeight": "100dp"
}

Because this example is a vertical scrolling grid, the childWidth array determines the width of each column. The auto dimension scales to fill the remaining space. Therefore, the calculated column widths are 200, 300, and 500 dp. The GridSequence arranges the children from the top-left and fills each row before moving on to the next row. The following figure shows the layout:

My alternative image text
Children positioned in vertically-scrolling grid with differing width columns