I'm trying to build a tile with a progress bar (showing the user's sleep time) and that when a user clicks it, it opens the main activity (app), but I can't figure out how to add the clickable modifier to my EdgeContentLayout
and when I add the clickable modifier to my text it doesn't even open the app.
Here's my MainTileService
:
/**
* Skeleton for a tile with no images.
*/
@OptIn(ExperimentalHorologistApi::class)
class MainTileService : SuspendingTileService() {
override suspend fun resourcesRequest(
requestParams: RequestBuilders.ResourcesRequest
): ResourceBuilders.Resources {
return ResourceBuilders.Resources.Builder()
.setVersion(RESOURCES_VERSION)
.addIdToImageMapping(
"sleep_icon",
ResourceBuilders.ImageResource.Builder()
.setAndroidResourceByResId(
ResourceBuilders.AndroidImageResourceByResId.Builder()
.setResourceId(R.drawable.sleep)
.build()
).build()
).build()
}
override suspend fun tileRequest(
requestParams: RequestBuilders.TileRequest
): TileBuilders.Tile {
val lastClickableId = requestParams.currentState.lastClickableId
if (lastClickableId === LAUNCH_APP_ID) {
Log.d("Tile", "Launching main activity...")
startActivity(packageManager.getLaunchIntentForPackage(packageName))
}
val sharedPreferences = getSharedPreferences(
SettingsBasics.SHARED_PREFERENCES.getKey(),
SettingsBasics.SHARED_PREFERENCES.getMode()
)
// Initialize managers
val timeManager = TimeManager()
val alarmManager = AlarmsManager()
// Get preferences
val useAlarm = sharedPreferences.getBoolean(Settings.ALARM.getKey(), Settings.ALARM.getDefaultAsBoolean())
val wakeTimeString = sharedPreferences.getString(Settings.WAKE_TIME.getKey(), Settings.WAKE_TIME.getDefault())
// Get next alarm
val nextAlarm = alarmManager.fetchAlarms(this);
// Calculate wake time
// between alarm and wake time
val wakeTime = timeManager.getWakeTime(
useAlarm,
nextAlarm,
wakeTimeString,
Settings.WAKE_TIME.getDefaultAsLocalTime()
);
// Calculate time difference
val sleepTime = timeManager.calculateTimeDifference(wakeTime.first)
// Calculate sleep quality from time diff
val sleepQuality = timeManager.calculateSleepQuality(sleepTime)
val singleTileTimeline = TimelineBuilders.Timeline.Builder().addTimelineEntry(
TimelineBuilders.TimelineEntry.Builder().setLayout(
LayoutElementBuilders.Layout.Builder().setRoot(
tileLayout(this, sleepTime, sleepQuality).build()
).build()
).build()
).build()
return TileBuilders.Tile.Builder()
.setResourcesVersion(RESOURCES_VERSION)
.setTileTimeline(singleTileTimeline)
.setFreshnessIntervalMillis(
// Every 5 minutes (60000 = 1m)
60000 * 5
)
.build()
}
}
Here's my tile layout:
private fun tileLayout(
context: Context,
sleepTime: TimeDifference,
sleepQuality: SleepQuality
): EdgeContentLayout.Builder {
val deviceParameters = buildDeviceParameters(context.resources)
return EdgeContentLayout.Builder(deviceParameters)
.setEdgeContent(
CircularProgressIndicator.Builder()
.setProgress(sleepTime.hours.toFloat() / DEFAULT_GOAL)
.setStartAngle(-165f)
.setEndAngle(165f)
.setCircularProgressIndicatorColors(
ProgressIndicatorColors(
TileColors.PrimaryColor,
TileColors.TrackColor
)
)
.build()
)
.setPrimaryLabelTextContent(
Text.Builder(context, "Sleep")
.setTypography(6.toInt())
.setColor(argb(TileColors.LightText))
.build()
)
.setSecondaryLabelTextContent(
Text.Builder(context, sleepQuality.getTitle())
.setTypography(Typography.TYPOGRAPHY_CAPTION1)
.setColor(argb(TileColors.White))
.build()
)
.setContent(
Spannable.Builder()
.addSpan(
SpanText.Builder()
.setText(sleepTime.hours.toString())
.setFontStyle(
FontStyle.PrimaryFontSize.getBuilder()
)
.build()
)
.addSpan(
SpanText.Builder()
.setText("h")
.setFontStyle(
FontStyle.SecondaryFontSize.getBuilder()
)
.build()
)
.addSpan(
SpanText.Builder()
.setText(" ")
.build()
)
.addSpan(
SpanText.Builder()
.setText(sleepTime.minutes.toString())
.setFontStyle(
FontStyle.PrimaryFontSize.getBuilder()
)
.build()
)
.addSpan(
SpanText.Builder()
.setText("m")
.setFontStyle(
FontStyle.SecondaryFontSize.getBuilder()
)
.build()
)
.build()
)
}
full code available on github
LayoutElementBuilders.Box.Builder
, then adding the clickable modifier, but that makes the tile blankI want a tile with a progress bar that when a user clicks on the tile, it launches the main activity (app)
This part that you've tried:
Wrapping the tile layout in a LayoutElementBuilders.Box.Builder, then adding the clickable modifier, but that makes the tile blank
is good. You're seeing a blank tile because Box by default has width and height set to wrap
, but EdgeContentLayout
's dimension is expand (i.e. when setting an expand child to a parent that wraps, that element won't be shown), to fix that you could do something like:
import androidx.wear.protolayout.DimensionBuilders.expand
Box.Builder()
.setWidth(expand())
.setHeight(expand())
.addContent(yourEdgeContentLayout)
.build()
Hope this helps!