アプリでタイルの提供を開始するには、アプリの build.gradle
ファイルに次の依存関係を追加します。
Groovy
dependencies { // Use to implement support for wear tiles implementation "androidx.wear.tiles:tiles:1.4.1" // Use to utilize standard components and layouts in your tiles implementation "androidx.wear.protolayout:protolayout:1.2.1" // Use to utilize components and layouts with Material Design in your tiles implementation "androidx.wear.protolayout:protolayout-material:1.2.1" // Use to include dynamic expressions in your tiles implementation "androidx.wear.protolayout:protolayout-expression:1.2.1" // Use to preview wear tiles in your own app debugImplementation "androidx.wear.tiles:tiles-renderer:1.4.1" // Use to fetch tiles from a tile provider in your tests testImplementation "androidx.wear.tiles:tiles-testing:1.4.1" }
Kotlin
dependencies { // Use to implement support for wear tiles implementation("androidx.wear.tiles:tiles:1.4.1") // Use to utilize standard components and layouts in your tiles implementation("androidx.wear.protolayout:protolayout:1.2.1") // Use to utilize components and layouts with Material Design in your tiles implementation("androidx.wear.protolayout:protolayout-material:1.2.1") // Use to include dynamic expressions in your tiles implementation("androidx.wear.protolayout:protolayout-expression:1.2.1") // Use to preview wear tiles in your own app debugImplementation("androidx.wear.tiles:tiles-renderer:1.4.1") // Use to fetch tiles from a tile provider in your tests testImplementation("androidx.wear.tiles:tiles-testing:1.4.1") }
主な概念
タイルは Android アプリと同じ方法で作成されず、次のような異なるコンセプトを使用します。
- レイアウト テンプレート: ディスプレイ上の視覚要素の全体的な配置を定義します。タイルは、ディスプレイの端に進行状況インジケーターを含む
EdgeContentLayout
レイアウト テンプレートを使用するか、このインジケーターを表示しないPrimaryLayout
を使用します。 - レイアウト要素:
Button
やChip
などの個々のグラフィック要素、またはColumn
、MultiButtonLayout
、MultiSlotLayout
などを使用してグループ化された複数の要素を表します。これらはレイアウト テンプレートに埋め込まれています。 - リソース:
ResourceBuilders.Resources
オブジェクトは、レイアウトのレンダリングに必要な Android リソース(画像)の Key-Value ペアのマップとバージョンで構成されています。 - タイムライン:
TimelineBuilders.Timeline
オブジェクトは、レイアウト オブジェクトの 1 つ以上のインスタンスのリストです。レンダラがレイアウト オブジェクトを切り替えるタイミング(特定の時間にレイアウトの表示を停止するなど)を示すために、さまざまなメカニズムと式を指定できます。 - 状態: タイル間とアプリ間で渡される
StateBuilders.State
型のデータ構造。これにより、2 つのコンポーネントが相互に通信できるようになります。たとえば、タイルでボタンがタップされると、その状態にボタンの ID が保持されます。マップを使用してデータ型を交換することもできます。 - タイル: タイルを表す
TileBuilders.Tile
オブジェクト。タイムライン、リソース バージョン ID、更新間隔、状態で構成されます。 - Protolayout: この用語は、さまざまなタイルに関連するクラスの名前に登場します。これは、さまざまな Wear OS サーフェスで使用されるグラフィック ライブラリである Wear OS Protolayout ライブラリを指します。
タイルを作成する
アプリからタイルを提供するには、TileService
タイプのサービスを実装して、マニフェストに登録します。これに基づいて、システムは onTileRequest()
の呼び出し時に必要なタイルをリクエストし、onTileResourcesRequest()
の呼び出し時に必要なリソースをリクエストします。
class MyTileService : TileService() { override fun onTileRequest(requestParams: RequestBuilders.TileRequest) = Futures.immediateFuture( Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTileTimeline( Timeline.fromLayoutElement( Text.Builder(this, "Hello World!") .setTypography(Typography.TYPOGRAPHY_BODY1) .setColor(argb(0xFFFFFFFF.toInt())) .build() ) ) .build() ) override fun onTileResourcesRequest(requestParams: ResourcesRequest) = Futures.immediateFuture( Resources.Builder() .setVersion(RESOURCES_VERSION) .build() ) }
次に、AndroidManifest.xml
ファイルの <application>
タグ内にサービスを追加します。
<service android:name=".snippets.tile.MyTileService" android:label="@string/tile_label" android:description="@string/tile_description" android:icon="@mipmap/ic_launcher" android:exported="true" android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER"> <intent-filter> <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" /> </intent-filter> <meta-data android:name="androidx.wear.tiles.PREVIEW" android:resource="@drawable/tile_preview" /> </service>
権限とインテント フィルタにより、このサービスがタイル プロバイダとして登録されます。
アイコン、ラベル、説明、プレビュー リソースは、ユーザーがスマートフォンまたはスマートウォッチでタイルを設定するときに表示されます。
アプリをデプロイし、タイルをタイルのカルーセルに追加します(タイルをプレビューするよりデベロッパー向けの方法もありますが、今は手動で行うだけです)。
図 1. 「Hello World」タイル。
完全な例については、GitHub のコードサンプルまたは codelab をご覧ください。
タイルの UI を作成する
タイルのレイアウトは、ビルダー パターンを使用して記述し、レイアウト コンテナと基本的なレイアウト要素からなるツリーのように作成します。各レイアウト要素にはプロパティがあり、さまざまなセッター メソッドで設定できます。
基本的なレイアウト要素
protolayout
ライブラリの次の視覚的要素とマテリアル コンポーネントがサポートされています。
Text
: テキスト文字列をレンダリングし、必要に応じて折り返します。Image
: 画像をレンダリングします。Spacer
: 要素間にパディングを設定します。背景色を設定するときは区切りとして機能します。
マテリアル コンポーネント
基本要素に加えて、protolayout-material
ライブラリにはマテリアル デザイン ユーザー インターフェースの推奨事項に沿ったタイルデザインを実現するためのコンポーネントが用意されています。
Button
: アイコンを含むようにデザインされた、クリック可能な円形のコンポーネント。Chip
: 最大 2 行のテキストと任意のアイコンを含むようにデザインされた、クリック可能なスタジアム形のコンポーネント。CompactChip
: 1 行のテキストを含むようにデザインされた、クリック可能なスタジアム形のコンポーネント。TitleChip
:Chip
に似ているが、タイトル テキストを表示できるように高さが大きくなっている、クリック可能なスタジアム形のコンポーネント。CircularProgressIndicator
:EdgeContentLayout
内に配置して画面の端に進行状況を表示できる、円形の進行状況インジケーター。
レイアウト コンテナ
次のコンテナとマテリアル レイアウトがサポートされています。
Row
: 子要素を水平方向に並べます。Column
: 子要素を垂直方向に並べます。Box
: 子要素を重ね合わせます。Arc
: 子要素を環状に並べます。Spannable
: テキストのセクションに特定のFontStyles
を適用し、テキストや画像の間に入れます。詳細については、Spannable をご覧ください。
どのコンテナにも、子を 1 つ以上含めることができます。子はコンテナにすることもできます。たとえば、Column
に子として複数の Row
要素を含めることができます。この場合、格子状のレイアウトになります。
一例として、コンテナ レイアウトと 2 つの子レイアウト要素を持つタイルは次のようになります。
Kotlin
private fun myLayout(): LayoutElement = Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VERTICAL_ALIGN_BOTTOM) .addContent(Text.Builder() .setText("Hello world") .build() ) .addContent(Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build()
Java
private LayoutElement myLayout() { return new Row.Builder() .setWidth(wrap()) .setHeight(expand()) .setVerticalAlignment(VALIGN_BOTTOM) .addContent(new Text.Builder() .setText("Hello world") .build() ) .addContent(new Image.Builder() .setResourceId("image_id") .setWidth(dp(24f)) .setHeight(dp(24f)) .build() ).build(); }
マテリアル レイアウト
基本的なレイアウトに加えて、protolayout-material
ライブラリには、特定の「スロット」内に要素を保持するための独自のレイアウトがいくつか用意されています。
PrimaryLayout
: 単一のプライマリ アクションCompactChip
を下部に配置し、その中央にコンテンツを重ねます。MultiSlotLayout
: プライマリ ラベルとセカンダリ ラベルを配置し、その間にオプションのコンテンツを配置して、下部にオプションのCompactChip
を配置します。MultiButtonLayout
: マテリアル ガイドラインに沿って並んだボタンのセットを配置します。EdgeContentLayout
:CircularProgressIndicator
など、コンテンツを画面の端に配置します。このレイアウトを使用すると、その中のコンテンツには適切な余白とパディングが自動的に適用されます。
円弧
サポートされている Arc
コンテナの子は次のとおりです。
ArcLine
: 円弧の周りに曲線をレンダリングします。ArcText
: 円弧の中に曲線テキストをレンダリングします。ArcAdapter
: 円弧の中に基本的なレイアウト要素をレンダリングし、円弧の接線上に描画します。
詳細については、それぞれの要素のリファレンス ドキュメントをご覧ください。
修飾子
利用可能なすべてのレイアウト要素に、必要に応じて修飾子を適用できます。修飾子は以下の目的で使用します。
- レイアウトの外観を変更する: たとえば、レイアウト要素に背景、枠線、パディングを追加します。
- レイアウトに関するメタデータを追加する: たとえば、スクリーン リーダーで使用するセマンティクス修飾子をレイアウト要素に追加します。
- 機能を追加する: たとえば、レイアウト要素にクリック可能な修飾子を追加して、タイルをインタラクティブにします。詳細については、タイルを操作するをご覧ください。
たとえば、次のコードサンプルに示すように、Image
のデフォルトの外観とメタデータをカスタマイズできます。
Kotlin
private fun myImage(): LayoutElement = Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(Modifiers.Builder() .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(Padding.Builder().setStart(dp(12f)).build()) .setSemantics(Semantics.builder() .setContentDescription("Image description") .build() ).build() ).build()
Java
private LayoutElement myImage() { return new Image.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .setModifiers(new Modifiers.Builder() .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build()) .setPadding(new Padding.Builder().setStart(dp(12f)).build()) .setSemantics(new Semantics.Builder() .setContentDescription("Image description") .build() ).build() ).build(); }
Spannable
Spannable
は、テキストと同様に要素をレイアウトする特別なタイプのコンテナです。大きなテキスト ブロック内の 1 つの部分文字列だけに別のスタイルを適用する場合に便利です。これは Text
要素では不可能です。
Spannable
コンテナは Span
の子で満たされます。他の子やネストされた Spannable
インスタンスは使用できません。
Span
の子には、次の 2 種類があります。
たとえば、次のコードサンプルに示すように、「Hello world」タイルの「world」を斜体にし、単語の間に画像を挿入できます。
Kotlin
private fun mySpannable(): LayoutElement = Spannable.Builder() .addSpan(SpanText.Builder() .setText("Hello ") .build() ) .addSpan(SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(SpanText.Builder() .setText("world") .setFontStyle(FontStyle.Builder() .setItalic(true) .build()) .build() ).build()
Java
private LayoutElement mySpannable() { return new Spannable.Builder() .addSpan(new SpanText.Builder() .setText("Hello ") .build() ) .addSpan(new SpanImage.Builder() .setWidth(dp(24f)) .setHeight(dp(24f)) .setResourceId("image_id") .build() ) .addSpan(new SpanText.Builder() .setText("world") .setFontStyle(newFontStyle.Builder() .setItalic(true) .build()) .build() ).build(); }
リソースを扱う
タイルはアプリのリソースにアクセスできません。これは、Android 画像 ID を Image
レイアウト要素に渡して解決することができないことを意味します。代わりに、onTileResourcesRequest()
メソッドをオーバーライドし、リソースを手動で指定します。
onTileResourcesRequest()
メソッド内で画像を指定する方法には次の 2 つがあります。
setAndroidResourceByResId()
を使用して、ドローアブル リソースを指定する。setInlineResource()
を使用して、動的な画像をByteArray
として指定する。
Kotlin
override fun onTileResourcesRequest( requestParams: ResourcesRequest ) = Futures.immediateFuture( Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", ImageResource.Builder() .setAndroidResourceByResId(AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", ImageResource.Builder() .setInlineResource(InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() )
Java
@Override protected ListenableFuture<Resources> onTileResourcesRequest( @NonNull ResourcesRequest requestParams ) { return Futures.immediateFuture( new Resources.Builder() .setVersion("1") .addIdToImageMapping("image_from_resource", new ImageResource.Builder() .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder() .setResourceId(R.drawable.image_id) .build() ).build() ) .addIdToImageMapping("image_inline", new ImageResource.Builder() .setInlineResource(new InlineImageResource.Builder() .setData(imageAsByteArray) .setWidthPx(48) .setHeightPx(48) .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565) .build() ).build() ).build() ); }
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- ProtoLayout 名前空間に移行する
- Compose の
ConstraintLayout
- アプリ用のカスタム クイック設定タイルを作成する