Support Tablets and Other Devices that Can Change Size

An Alexa Presentation Language (APL) document uses device characteristics to conditionally display content on different screen sizes. Some devices, such as tablets, can change screen size and other characteristics while your document is still displayed on the screen. For example, a user might invoke your skill on a tablet in landscape mode, and then flip the device into portrait mode.

You can build APL documents that adapt to device changes that occur while device is displaying your document.

About changing device characteristics

When you send Alexa an APL document with the RenderDocument directive, Alexa sets the environment and viewport constants in the data-binding context. You use these properties in your APL document to define conditional logic, such as displaying one layout on a landscape screen and a different layout on a portrait screen.

By default, the viewport and environment constants available to your document don't change after the device renders the document on the screen. However, some devices can change screen size and other characteristics while displaying your document. When a user turns a tablet from landscape to portrait, the screen dimensions change.

You can choose how your APL document handles device changes that take place while the document is displayed:

  • Do nothing – By default, your APL document displays scaled down to the hub viewport and locked to a portrait orientation.
  • Resize the document – Use the same layout for the content, but resize the layout to fit the new screen. The existing environment and viewport constants aren't updated, so they continue to reflect the original device characteristics.
  • Reinflate the document – Rebuild the entire document, following the same process as when initially displaying the document on the screen. Alexa creates a new, updated data-binding context with environment and viewport constants that match the new screen size. This option lets you change the layout of the components in the document to match the new screen size.

Resizing the document is a faster operation, but is less flexible because you can't change the layout. This option works best for simpler layouts. For example, a Pager that displays a slideshow of images might look good when resized. Resizing is also automatic after you enable the option.

Reinflating the document lets you fully adapt your layout to the size and shape of your device, but it is also a slower operation. When you choose to reinflate, you also must consider whether to preserve the current document state.

User experience with APL on Amazon tablets

Users interact with APL content on Fire tablets in two different ways:

  • Show mode – Turns the tablet into a visual display like an Echo Show device. APL content displays in a landscape view. When the tablet is in Show mode, the screen remains locked in the landscape orientation, so the resizing and reinflation concepts don't apply. For more about enabling Show mode, see Switch to Show Mode on Your Fire Tablet.
  • Tablet mode with Alexa Hands-Free – Normal tablet functions are available. The user can speak to Alexa on the tablet to invoke your skill. How the tablet displays your content depends on your skill:
    • By default, your APL document displays scaled down to the hub viewport and locked to a portrait orientation.
    • If you opt-in to allow resizing, the tablet displays your content in either portrait or landscape depending on the orientation of the tablet. You can use automatic resizing or reinflation to control how the content looks on the different orientations.

Example of resize versus reinflate

The following example document displays an image and text. The document uses the viewport.width and viewport.height properties in the data binding context to determine the orientation of the device and adjust the layout accordingly. A landscape viewport displays the image and text side-by-side, and a portrait viewport displays the image and text in a vertical column.

Copied to clipboard.

{
  "type": "APL",
  "version": "1.7",
  "import": [
    {
      "name": "alexa-styles",
      "version": "1.3.0"
    }
  ],
  "resources": [
    {
      "booleans": {
        "isLandscape": "${viewport.width > viewport.height}"
      }
    }
  ],
  "mainTemplate": {
    "parameters": [
      "exampleData"
    ],
    "item": {
      "type": "Container",
      "direction": "${@isLandscape ? 'row' : 'column'}",
      "padding": "@marginHorizontal, @spacingMedium",
      "items": [
        {
          "type": "Image",
          "scale": "best-fit",
          "width": "${@isLandscape ? 0 : '100%'}",
          "height": "${@isLandscape ? '100%' : 0}",
          "grow": 0.5,
          "source": "${exampleData.image}"
        },
        {
          "type": "ScrollView",
          "width": "${@isLandscape ? 0 : '100%'}",
          "height": "${@isLandscape ? '100%' : 0}",
          "grow": 0.5,
          "spacing": "@spacingMedium",
          "item": {
            "type": "Text",
            "fontSize": 20,
            "text": "${exampleData.text}"
          }
        }
      ]
    }
  },
  "settings": {
    "supportsResizing": true
  }
}

Assume the user invokes the skill on a tablet in landscape orientation. The APL runtime calculates the value of the isLandscape boolean as true and displays the layout with the image on the left and the text on the right.

A conditional layout that displays an image on the left and scrolling text on the right on a landscape viewport
A conditional layout that displays an image on the left and scrolling text on the right on a landscape viewport

While the document is still on the screen, the user turns the tablet to portrait mode. The result of this action depends on whether you choose to resize or reinflate the document.

If you let APL automatically resize your content, the document structure remains the same. The conditional statements in the document that provide a different experience for a portrait viewport aren't reevaluated. The original values in viewport.width and viewport.height remain the same and continue to describe a landscape device. The isLandscape boolean is still "true".

Therefore, the device resizes the two components to fit on the narrower portrait screen.

A document initially displayed in landscape, and then resized to fit a portrait viewport
A document initially displayed in landscape, and then resized to fit a portrait viewport

In contrast, when you use the reinflate option, Alexa creates a new data-binding context with new values for viewport.width and viewport.height and then recalculates the value of the isLandscape boolean. Because this resource now evaluates to true, the device renders the layout with the image and text in a vertical column.

A document initially displayed in landscape, and then reinflated for a portrait viewport
A document initially displayed in landscape, and then reinflated for a portrait viewport

Let APL automatically resize your document

APL can automatically resize your document when the device characteristics change. For best results, use this option with simple layouts. Make your document as responsive as possible.

To enable automatic resizing

  1. Build a responsive document that doesn't use absolute dimensions.
  2. In the document settings, enable the supportsResizing option:
     {
       "settings": {
         "supportsResizing": true
       }
     }
    
  3. Optionally configure the onConfigChange handler for the document with any commands you want to run when the system detects a change in the width and height of the screen.
  4. Test the resizing with a tablet to verify that your document looks good when resized.

To effectively test how your skill works on a device that changes screen sizes, invoke your skill on a tablet and then change the orientation between portrait and landscape.

Although you can use the Mobile viewports in the authoring tool and simulator to see how your document looks on different tablet viewports, these tools don't show you the results of resizing your document when it is already displayed on the screen:

  • In the authoring tool, when you switch to a different viewport, the tool inflates your document from scratch and sets properties like viewport.width to the actual width of the simulated device. Any conditional statements that use the viewport property are evaluated.
  • On an actual tablet, when you display your document in one orientation and then turn it to the other orientation, the device resizes your document without updating and reevaluating the viewport property. Any conditional statements that use the viewport property are not re-evaluated.

Reinflate the document when the device characteristics change

You can configure your document to fully reinflate the document when device characteristics change. This option rebuilds the entire document, following the same process as when initially displaying the document on the screen. Use this option when you want to change the layout to accommodate different screens sizes and orientations.

To configure the document to reinflate

  1. Build a responsive document. Use conditional statements to build different layouts for portrait and landscape viewports.

    As a best practice, use the @viewportOrientation resource provided in the alexa-viewport-profiles package to determine the orientation of the viewport instead of accessing the viewport property directly. The @viewportOrientation resources uses the viewport.height and viewport.width properties to determine the orientation.

       {
         "resources": [
           {
             "booleans": {
               "isLandscape": "${@viewportOrientation == @viewportOrientationLandscape}"
             }
           }
         ]
       }
    
  2. In the document settings, enable the supportsResizing option:
     {
       "settings": {
         "supportsResizing": true
       }
     }
    
  3. Configure the document onConfigChange handler to run the Reinflate command.
     {
       "onConfigChange": {
         "type": "Reinflate"
       }
     }
    
  4. Optionally configure the document onConfigChange handler with any other commands you want to run when the system detects a change in the width and height of the screen.
  5. Optionally set the preserve property to save state during the reinflation. For details, see Preserve component properties when reinflating the document.
  6. Test your document with a tablet to see the results of reinflating the document.

You can use the Mobile viewports in the authoring tool and simulator to partially test the experience.

  • In the authoring tool, when you switch to a different viewport, the tool inflates your document from scratch and sets properties like viewport.width to the actual width of the simulated device. Any conditional statements or resources that use the viewport property are evaluated. The Reinflate command also inflates the document from scratch and updates viewport, so authoring does approximate the results of reinflation.
  • You can't test the results of preserving state with the preserve property in the authoring tool or simulator. Use a tablet device for testing preserve.

Preserve component properties when reinflating the document

The Reinflate command rebuilds the entire document, following the same process as when initially displaying the document on the screen. By default, this resets component properties that represent the document state when you ran the Reinflate command. For example, in a document that displays a ScrollView, the scroll position resets to the top of the component when the document reinflates. If the user scrolls through the content and then changes the tablet orientation, losing their place in the content is a poor experience.

To improve the experience, use the preserve property to save state information during reinflation. The preserve property is base component property that accepts an array of dynamic and bound properties to save during reinflation.

The following example saves the scrollOffset property on a ScrollView.

{
  "type": "ScrollView",
  "id": "textScrollViewId",
  "preserve": [
    "scrollOffset"
  ],
  "width": "${@isLandscape ? 0 : '100%'}",
  "height": "${@isLandscape ? '100%' : 0}",
  "grow": 0.5,
  "spacing": "@spacingMedium",
  "item": {
    "type": "Text",
    "fontSize": 20,
    "text": "${exampleData.text}"
  }
}

You must set the id for a component when you set preserve. When you run Reinflate command, Alexa checks the original document hierarchy for a component with the id and then copies the values for the specified preserve properties to the corresponding component in the reinflated document. In the previous example, Alexa saves the scrollOffset value for the ScrollView with the ID textScrollViewId and copies that offset to the new ScrollView. As a result, after the document renders on the new screen size, the ScrollView adjusts to the original scroll position.

The specific values you can set for a particular component depend on the component type.

You can also save your own bound properties that you create with the bind property.

The following document example shows how to fully reinflate and preserve state to display different layouts for portrait and landscape screens. This example uses the @viewportOrientation resource provided in the alexa-viewport-profiles package to determine the orientation of the viewport.

The document and component onMount commands run after the document reinflates. You can use these handlers to resume playing media content. The following example shows a document that resumes a video after the viewport size changes. The preserve property saves the currently-playing source and the playingState. The document onMount handler runs the ControlMedia command to resume the video.