APLレイアウト



APLレイアウト

Alexa Presentation Language(APL)レイアウトは名前付きの複合コンポーネントであり、APLドキュメントまたはパッケージで定義されています。レイアウトは、別の名前付きレイアウトやプリミティブコンポーネントのコレクションに展開(inflates)される関数です。APLレイアウトでは、parameters配列内で引数を渡すことができます。各種コンポーネントを現在のデータバインディングコンテキストに応じてインフレートできるため、APLレイアウトのインフレートは条件付きで行われます。

レイアウトについて

レイアウトは、APLドキュメントまたはパッケージのlayoutsプロパティで定義します。このプロパティの引数は文字列とオブジェクトのマッピングです。その後、コンポーネントのtypeプロパティをレイアウト名に設定することで、ドキュメントにレイアウトを呼び出すことができます。

たとえば、titlelogoという2つのパラメーターを受け取るHeaderLayoutExampleレイアウトがあるとします。レイアウト内で、Textコンポーネントはtitleパラメーターに指定された値を使用し、Imageコンポーネントはlogoパラメーターに指定された値を使用します。

円形のviewportの場合、HeaderLayoutExampleレイアウトは列方向のContainerにインフレートされ、タイトルの前にロゴが配置されます。長方形のviewportの場合、このレイアウトは行方向のContainerにインフレートされ、同じ行のタイトルの後にロゴが配置されます。

以下は、HeaderLayoutExampleのAPLコードの例です。

{
  "layouts": {
    "HeaderLayoutExample": {
      "description": "タイトルとロゴ付きの基本的なヘッダー",
      "parameters": [
        {
          "name": "title",
          "type": "string"
        },
        {
          "name": "logo",
          "type": "string",
          "default": "https://d2o906d8ln7ui1.cloudfront.net/images/cheeseskillicon.png"
        }
      ],
      "items": [
        {
          "when": "${viewport.shape == 'round'}",
          "type": "Container",
          "direction": "column",
          "alignItems": "center",
          "padding": [64,32],
          "items": [
            {
              "type": "Image",
              "source": "${logo}",
              "height": 36,
              "width": 36
            },
            {
              "type": "Text",
              "text": "${title}",
              "style": "textStyleBody",
              "maxLines": 1
            }
          ]
        },
        {
          "type": "Container",
          "direction": "row",
          "padding": [64,32],
          "width": "100%",
          "justifyContent": "spaceBetween",
          "items": [
            {
              "type": "Text",
              "text": "${title}",
              "width": "90%",
              "style": "textStyleBody",
              "maxLines": 2
            },
            {
              "type": "Image",
              "source": "${logo}",
              "height": 50,
              "width": 50
            }
          ]
        }
      ]
    }
  }
}

ドキュメントでレイアウトを呼び出すには、コンポーネントのtypeにレイアウト名を使用してから、パラメーターを渡します。以下は、HeaderLayoutExampleレイアウトを呼び出す方法の例です。

{
  "mainTemplate": {
    "parameters": [
      "payload"
    ],
    "items": [
      {
        "type": "HeaderLayoutExample",
        "title": "これはタイトルに使用するテキストです"
      }
    ]
  }
}

レイアウトのプロパティ

レイアウトオブジェクトには次の表のプロパティがあります。

プロパティ 必須 説明

bind

バインドの配列

データバインディングコンテキストに追加する式です。

description

文字列

このレイアウトの説明を指定します。

itemitems

コンポーネントの配列

インフレートするコンポーネントです。itemsに配列が含まれる場合、レイアウトはwhen条件がtrueになった最初のコンポーネントをインフレートします。

parameters

パラメーターの配列

このレイアウトに渡すことができるパラメーターの配列です。

bind

レイアウトのbindプロパティは、レイアウトおよびその子のデータバインディングコンテキストを展開するためのものです。バインディング配列の各バインディングオブジェクトには、次のプロパティが含まれます。

プロパティ デフォルト 説明

name

文字列

このバインディングで使用する名前です。有効な名前を設定する必要があります。

value

任意

必須

このバインディングに割り当てる値です。

type


有効な値: anybooleanstringnumberdimentioncolor

any

バインディング値のデータ型です。

bindプロパティはparametersプロパティの後に評価されます。バインディングは配列順にデータバインディングコンテキストに追加されます。配列で後に定義されたバインディングは、配列の前に定義されたバインディングの結果を使用できます。

以下の例では、SalutationFormalNameバインディングに依存し、FormalNameはTitleおよびLastNameパラメーターに依存します。

{
  "MyLayout": {
    "parameters": [
      {"name":"Title","default":"Dr."},
      {"name":"FirstName"},
      {"name":"LastName"}
    ],
    "bind": [
      {"name":"FormalName","value":"${Title} ${LastName}"},
      {"name":"Salutation","value":"Dear ${FormalName}"}
    ]
  }
}

定義したバインディングがコンポーネントのプロパティ名と競合しないよう、バインディングの変数名は大文字にします。前の例にあるとおり、titleではなくTitleを使用します。

APLのプリミティブコンポーネントもローカル変数のバインディングをサポートしています。bindプロパティを参照してください。

item、items

itemプロパティには単一のコンポーネントを、itemsプロパティにはコンポーネントの配列を指定します。ほかのレイアウトも、layoutsオブジェクトに既にインポート済みまたは定義済みであれば、itemsに含めることができます。APLデータバインディングの構文を参照してください。

itemsに配列が含まれる場合、レイアウトはwhen条件がtrueになった最初のコンポーネントをインフレートします。

parameters

parametersは、呼び出し時にレイアウトに渡すことができる名前付きの値のことです。各パラメーターは、以下の表のプロパティを持つオブジェクトです。

プロパティ 必須 説明

default

任意

パラメーターを指定しない場合に適用するデフォルト値です。デフォルトは空白です。

description

文字列

このパラメーターの用途について説明する任意の詳細です。

name

文字列/その他

一意のパラメーター名です。名前には、大文字または小文字の英字で始まり、スペースを含まない名前を設定します。

type

✕ パラメーターの型です。デフォルトはanyです。有効な値:anyarraybooleancolorcomponentdimensionintegermapnumberobjectstring

手間を省くため、パラメーターオブジェクトの代わりに単一のパラメーター名を使用できます。たとえば、{ "name": "title", ... }の代わりに、titleだけを定義します。これにより、パラメーターに渡す値にデフォルト値や型の強制が不要になるため、コードを簡素化できます。明確に定義するには、完全なパラメーターオブジェクトを使用することをお勧めします。

レイアウトのインフレート

APLは、次のアルゴリズムに従ってレイアウトをインフレートします。

  1. 各parameterを評価し、データバインディングコンテキストに追加します。
  2. 1つの子のみのインフレートアルゴリズムを使ってitemまたはitemsプロパティを評価します。
  3. レイアウトには割り当てられているが、名前付きパラメーター、項目、型に一致しないプロパティを、評価のために項目に渡します。

以下は、簡単なレイアウトを定義するコード例です。

"myLayout": {
  "parameters": [
    "title",
    "subtitle"
  ],
  "item": [
    {
      "when": "${viewport.width > viewport.height}",
      "type": "Text",
      "text": "<b>${title}:</b> ${subtitle}",
      "style": "textStyleDisplay1"
    },
    {
      "type": "Text",
      "text": "<b>${title}</b><br>${subtitle}",
      "style": "textStyleDisplay2"
    }
  ]
}

以下の例では、このレイアウトを呼び出して、titlesubtitlecolorの3つのパラメーターを渡します。colorパラメーターは、myLayoutのプロパティとして指定されていません。

{
	"type": "myLayout",
	"title": "フランケンシュタイン",
	"subtitle": "あるいは現代のプロメテウス",
	"color": "green"
}

ユーザーのデバイス画面が横長である場合を考えてみます。インフレーションロジックは以下を行います。

  1. 「title」と「subtitle」のパラメーターをデータバインディングコンテキストに追加します。
  2. itemプロパティを評価し、when条件がtrueに評価された最初のコンポーネントを探します。ユーザーのデバイス画面は横長のため、APLはitems配列のfirstのコンポーネントを選択します。
  3. 追加のプロパティがあれば、すべて選択したitemに渡します。この例では、colorプロパティをレイアウトに渡します。このプロパティは、myLayoutに定義されたプロパティのいずれとも一致していません。このため、このプロパティを選択された項目に渡します。

最終的には、次のようなTextコンポーネントになります。

{
	"type": "Text",
	"text": "<b>フランケンシュタイン</b>:あるいは現代のプロメテウス",
	"style": "textStyleDisplay1",
	"color": "green"
}