我按照 WatchOS 文档创建表盘。我可以毫无问题地在表盘上绘制任何东西,但是,当我尝试渲染任何复杂功能时,它并没有出现。
package com.example.mywatchface
import android.graphics.*
import android.util.Log
import android.view.SurfaceHolder
import androidx.core.content.ContextCompat
import androidx.wear.watchface.*
import androidx.wear.watchface.complications.ComplicationSlotBounds
import androidx.wear.watchface.complications.DefaultComplicationDataSourcePolicy
import androidx.wear.watchface.complications.SystemDataSources
import androidx.wear.watchface.complications.data.ComplicationType
import androidx.wear.watchface.complications.rendering.CanvasComplicationDrawable
import androidx.wear.watchface.complications.rendering.ComplicationDrawable
import androidx.wear.watchface.style.CurrentUserStyleRepository
import androidx.wear.watchface.style.UserStyleSchema
import java.time.ZonedDateTime
/**
* Updates rate in milliseconds for interactive mode. We update once a second to advance the
* second hand.
*/
private const val INTERACTIVE_UPDATE_RATE_MS = 1000
/**
* Handler message id for updating the time periodically in interactive mode.
*/
private const val MSG_UPDATE_TIME = 0
private const val HOUR_STROKE_WIDTH = 5f
private const val MINUTE_STROKE_WIDTH = 3f
private const val SECOND_TICK_STROKE_WIDTH = 2f
private const val CENTER_GAP_AND_CIRCLE_RADIUS = 4f
private const val SHADOW_RADIUS = 6f
class MyWatchFace : WatchFaceService() {
inner class MySharedAssets : Renderer.SharedAssets {
override fun onDestroy() {
}
}
/**
* The watch face itself, which includes the renderer for drawing.
*/
override suspend fun createWatchFace(
surfaceHolder: SurfaceHolder,
watchState: WatchState,
complicationSlotsManager: ComplicationSlotsManager,
currentUserStyleRepository: CurrentUserStyleRepository
): WatchFace {
return WatchFace(
WatchFaceType.DIGITAL,
object : Renderer.CanvasRenderer2<MySharedAssets>(
surfaceHolder,
currentUserStyleRepository,
watchState,
CanvasType.HARDWARE,
interactiveDrawModeUpdateDelayMillis = 16,
clearWithBackgroundTintBeforeRenderingHighlightLayer = true
) {
override suspend fun createSharedAssets(): MySharedAssets {
return MySharedAssets()
}
override fun renderHighlightLayer(
canvas: Canvas,
bounds: Rect,
zonedDateTime: ZonedDateTime,
sharedAssets: MySharedAssets
) {
}
override fun render(
canvas: Canvas,
bounds: Rect,
zonedDateTime: ZonedDateTime,
sharedAssets: MySharedAssets
) {
for ((_, complication) in complicationSlotsManager.complicationSlots) {
if (complication.enabled) {
Log.d("Hey", "hey")
complication.render(canvas, zonedDateTime, renderParameters)
}
}
var paint = Paint()
paint.color = ContextCompat.getColor(baseContext, R.color.watch_face_hands)
paint.textSize = 100f
paint.isAntiAlias = true
paint.style = Paint.Style.STROKE
paint.strokeWidth = 2f
val hours = zonedDateTime.hour
val minutes = zonedDateTime.minute
val clockHeight = (paint.fontMetrics.descent + paint.fontMetrics.ascent)
val time = String.format("%02d:%02d", hours, minutes)
drawText(canvas, time, paint, 0f, 0f)
paint = Paint()
paint.color = ContextCompat.getColor(baseContext, R.color.watch_date)
paint.textSize = 20f
paint.isAntiAlias = true
paint.typeface = Typeface.SANS_SERIF
val dayOfWeek = zonedDateTime.dayOfWeek.name.substring(0, 3)
val month = zonedDateTime.month.name
val dayOfMonth = zonedDateTime.dayOfMonth
val dateHeight = paint.fontMetrics.descent + paint.fontMetrics.ascent;
val date = String.format("%s, %s %d", dayOfWeek, month, dayOfMonth)
drawText(canvas, date, paint, 0f, clockHeight / 2 + dateHeight - 5f)
}
}
)
}
private fun drawText(
canvas: Canvas,
text: String,
paint: Paint,
offsetX: Float,
offsetY: Float
) {
val timeWidth = paint.measureText(text)
val timeHeight = (paint.fontMetrics.descent + paint.fontMetrics.ascent) / 2
val startX = (canvas.width.toFloat() - timeWidth) / 2 + offsetX
val startY = canvas.height.toFloat() / 2 - timeHeight + offsetY
canvas.drawText(text, startX, startY, paint)
}
/**
* The specification of settings the watch face supports.
* This is similar to a database schema.
*/
override fun createUserStyleSchema(): UserStyleSchema {
return super.createUserStyleSchema()
}
/**
* The complication slot configuration for the watchface.
*/
override fun createComplicationSlotsManager(currentUserStyleRepository: CurrentUserStyleRepository): ComplicationSlotsManager {
val canvasComplicationFactory = CanvasComplicationFactory { watchState, listener ->
val complicationDrawable = ComplicationDrawable(this)
complicationDrawable.activeStyle.backgroundColor = getColor(R.color.watch_date)
complicationDrawable.activeStyle.textColor = getColor(R.color.watch_date)
complicationDrawable.activeStyle.iconColor = getColor(R.color.watch_date)
complicationDrawable.activeStyle.textSize = 20
CanvasComplicationDrawable(complicationDrawable, watchState, listener)
}
return ComplicationSlotsManager(
listOf(
ComplicationSlot.createRoundRectComplicationSlotBuilder(
0,
canvasComplicationFactory,
listOf(
ComplicationType.RANGED_VALUE,
ComplicationType.LONG_TEXT,
ComplicationType.SHORT_TEXT,
ComplicationType.MONOCHROMATIC_IMAGE,
ComplicationType.SMALL_IMAGE
),
DefaultComplicationDataSourcePolicy(
SystemDataSources.DATA_SOURCE_WORLD_CLOCK,
ComplicationType.SHORT_TEXT
),
ComplicationSlotBounds(RectF(0.1f, 0.5625f, 0.4f, 0.8125f))
).build()
),
currentUserStyleRepository
)
}
}
这基本上是整个班级。 createComplicationSlotManager 应该创建 ComplicationSlots。为了进行测试,我使用了安全的并发症数据源(根据文档不需要观察权限的数据源),这意味着权限不应该有任何问题。我试图更改活动样式...我想也许出于某种原因,并发症会呈现为透明或黑色...所以这就是为什么我无法在黑屏上看到它。它没有帮助。当我检查复杂功能是否在渲染函数中“启用”时,它返回 true。所以当我在 render 函数中调用 render 方法时,并发症绝对不是“null”。
老实说,我没有想法,文档示例有点过时(他们在那里使用的一些东西被贬低了)。 ChatGPT 也无济于事,因为它是根据 2021 年的数据进行训练的,而当时的文档完全不同。
如有任何指点/帮助,我将不胜感激。
此外,作为旁注,如果有人可以向我解释如何选择 ComplicationSlotBounds,我将不胜感激。现在我使用文档示例中的值,但我想更好地了解如何正确选择它们。我假设这基本上是屏幕上复杂功能的位置,并且基本上在 0 - 1 的范围内,这意味着与屏幕尺寸相关的比例?!
将
ComplicationSlot.createRoundRectComplicationSlotBuilder
的 id 从 0 更改为 101。
经证实,除非是101或更高,否则它不起作用。
ComplicationSlotBounds 是屏幕的百分比,显示时您会看到。