WearOS Complication rendering does not show up on the watchface

问题描述 投票:0回答:1

我按照 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 的范围内,这意味着与屏幕尺寸相关的比例?!

wear-os watch-face-api android-wear-complication
1个回答
0
投票

ComplicationSlot.createRoundRectComplicationSlotBuilder
的 id 从 0 更改为 101。 经证实,除非是101或更高,否则它不起作用。

ComplicationSlotBounds 是屏幕的百分比,显示时您会看到。

© www.soinside.com 2019 - 2024. All rights reserved.