From d43c98f0253970064b6ed2c96a0a033ad91ff779 Mon Sep 17 00:00:00 2001 From: Michael Stillwell Date: Fri, 14 Nov 2025 15:15:50 +0000 Subject: [PATCH 1/3] Add snippets for /training/wearables/tiles/debug --- .../com/example/wear/snippets/tile/Preview.kt | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 wear/src/main/java/com/example/wear/snippets/tile/Preview.kt diff --git a/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt new file mode 100644 index 000000000..b4279a3f8 --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wear.snippets.tile + +import android.content.Context +import androidx.annotation.DrawableRes +import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters +import androidx.wear.protolayout.ResourceBuilders +import androidx.wear.protolayout.material3.materialScope +import androidx.wear.protolayout.material3.primaryLayout +import androidx.wear.protolayout.material3.text +import androidx.wear.protolayout.types.layoutString +import androidx.wear.tiles.tooling.preview.Preview +import androidx.wear.tiles.tooling.preview.TilePreviewData +import androidx.wear.tiles.tooling.preview.TilePreviewHelper +import androidx.wear.tooling.preview.devices.WearDevices +import androidx.wear.protolayout.ResourceBuilders.Resources +import androidx.wear.protolayout.expression.DynamicDataBuilders +import androidx.wear.protolayout.expression.PlatformDataValues +import androidx.wear.protolayout.expression.PlatformHealthSources +import com.example.wear.R + +// [START android_wear_tile_preview_simple] +@Preview(device = WearDevices.SMALL_ROUND) +@Preview(device = WearDevices.LARGE_ROUND) +fun tilePreview(context: Context) = TilePreviewData { request -> + TilePreviewHelper.singleTimelineEntryTileBuilder( + buildMyTileLayout(context, request.deviceConfiguration) + ).build() +} +// [END android_wear_tile_preview_simple] + +fun buildMyTileLayout( + context: Context, + deviceParameters: DeviceParameters, +) = materialScope(context = context, deviceConfiguration = deviceParameters) { + primaryLayout( + mainSlot = { + text("Hello world!".layoutString) + } + ) + } + +private const val RESOURCES_VERSION = "1" +private const val myImageId = "myImageId" + +// [START android_wear_tile_preview_resources] +@Preview(device = WearDevices.SMALL_ROUND) +fun previewWithResources(context: Context) = TilePreviewData( + onTileResourceRequest = { request -> + Resources.Builder() + .setVersion(RESOURCES_VERSION) + .addIdToImageMapping( + myImageId, getImageById(R.drawable.animated_walk)) + .build() + }, + onTileRequest = { request -> + TilePreviewHelper.singleTimelineEntryTileBuilder( + buildMyTileLayout(context, request.deviceConfiguration) + ).build() + } +) +// [END android_wear_tile_preview_resources] + +fun getImageById( + @DrawableRes id: Int, +): ResourceBuilders.ImageResource = + ResourceBuilders.ImageResource.Builder() + .setAndroidResourceByResId( + ResourceBuilders.AndroidImageResourceByResId.Builder() + .setResourceId(id) + .build(), + ) + .build() + +// [START android_wear_tile_preview_platform] +@Preview(device = WearDevices.SMALL_ROUND) +fun previewWithPlatformOverride(context: Context) = TilePreviewData( + platformDataValues = PlatformDataValues.of( + PlatformHealthSources.Keys.HEART_RATE_BPM, + DynamicDataBuilders.DynamicDataValue.fromFloat(160f) + ), + onTileRequest = { request -> + TilePreviewHelper.singleTimelineEntryTileBuilder( + buildMyTileLayout(context, request.deviceConfiguration) + ).build() + } +) +// [END android_wear_tile_preview_platform] From f7bffb4e13c96c75078bdd70d1c3fa07a5adfc0a Mon Sep 17 00:00:00 2001 From: Michael Stillwell Date: Fri, 14 Nov 2025 16:46:53 +0000 Subject: [PATCH 2/3] Create dynamic preview --- .../com/example/wear/snippets/tile/Preview.kt | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt index b4279a3f8..cd8d02065 100644 --- a/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt +++ b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt @@ -23,7 +23,7 @@ import androidx.wear.protolayout.ResourceBuilders import androidx.wear.protolayout.material3.materialScope import androidx.wear.protolayout.material3.primaryLayout import androidx.wear.protolayout.material3.text -import androidx.wear.protolayout.types.layoutString +import androidx.wear.protolayout.types.stringLayoutConstraint import androidx.wear.tiles.tooling.preview.Preview import androidx.wear.tiles.tooling.preview.TilePreviewData import androidx.wear.tiles.tooling.preview.TilePreviewHelper @@ -33,6 +33,8 @@ import androidx.wear.protolayout.expression.DynamicDataBuilders import androidx.wear.protolayout.expression.PlatformDataValues import androidx.wear.protolayout.expression.PlatformHealthSources import com.example.wear.R +import androidx.wear.protolayout.types.layoutString +import androidx.wear.protolayout.types.asLayoutString // [START android_wear_tile_preview_simple] @Preview(device = WearDevices.SMALL_ROUND) @@ -65,7 +67,9 @@ fun previewWithResources(context: Context) = TilePreviewData( Resources.Builder() .setVersion(RESOURCES_VERSION) .addIdToImageMapping( - myImageId, getImageById(R.drawable.animated_walk)) + myImageId, + getImageById(R.drawable.animated_walk) + ) .build() }, onTileRequest = { request -> @@ -87,6 +91,22 @@ fun getImageById( ) .build() +fun buildMyTileLayoutDynamic( + context: Context, + deviceParameters: DeviceParameters, +) = materialScope(context = context, deviceConfiguration = deviceParameters) { + primaryLayout( + mainSlot = { + text( + text = + PlatformHealthSources.heartRateBpm() + .format() + .asLayoutString("--", stringLayoutConstraint("999")) + ) + } + ) +} + // [START android_wear_tile_preview_platform] @Preview(device = WearDevices.SMALL_ROUND) fun previewWithPlatformOverride(context: Context) = TilePreviewData( @@ -96,7 +116,7 @@ fun previewWithPlatformOverride(context: Context) = TilePreviewData( ), onTileRequest = { request -> TilePreviewHelper.singleTimelineEntryTileBuilder( - buildMyTileLayout(context, request.deviceConfiguration) + buildMyTileLayoutDynamic(context, request.deviceConfiguration) ).build() } ) From dcdae0975f592dc66f4c5531f4401295dba225d6 Mon Sep 17 00:00:00 2001 From: Michael Stillwell Date: Fri, 14 Nov 2025 17:06:53 +0000 Subject: [PATCH 3/3] Suppress lint warnings for code sample --- wear/src/main/java/com/example/wear/snippets/tile/Preview.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt index cd8d02065..dc259b741 100644 --- a/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt +++ b/wear/src/main/java/com/example/wear/snippets/tile/Preview.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:Suppress("MissingPermission") + package com.example.wear.snippets.tile import android.content.Context