카드에 동적 업데이트 표시

Tiles 1.2부터는 동적 표현식을 사용하여 플랫폼 데이터 업데이트를 스트리밍할 수 있습니다. 그런 다음 이러한 업데이트를 카드의 애니메이션에 연결할 수 있습니다. 앱에는 1초에 한 번 이 값의 업데이트가 제공됩니다.

동적 표현식을 사용하면 콘텐츠가 변경되어도 카드 전체를 새로고침할 필요가 없습니다. 카드에서 보다 시선을 사로잡는 경험을 만들려면 이러한 동적 객체에 애니메이션을 적용하세요.

동적 표현식을 데이터 소스에 연결

androidx.wear.protolayoutandroidx.wear.protolayout.material 네임스페이스에는 필드에서 동적 표현식을 받는 클래스가 여럿 포함되어 있습니다. 몇 가지 예는 다음과 같습니다.

카드에 포함된 요소의 한 가지 가능한 값으로 동적 표현식을 사용하려면, 요소의 대응되는 *Prop 동적 속성 유형을 사용하고 동적 속성 유형의 빌더 클래스의 setDynamicValue() 메서드에 데이터 소스를 전달합니다.

카드는 다음과 같은 동적 속성 유형을 지원합니다.

실제 크기(색상을 제외한 카드의 모든 값)에 영향을 주는 동적 표현식을 사용할 때는 문자열 형식과 같은 관련 제약 조건도 지정해야 합니다. 이러한 제약 조건을 사용하면 시스템 렌더기가 카드 내에서 값이 차지할 수 있는 최대 공간을 확인할 수 있습니다. 일반적으로 이러한 제약 조건은 setLayoutConstraintsForDynamic*으로 시작하는 메서드를 호출하여 동적 표현식 수준이 아닌 요소 수준에서 지정해야 합니다.

다음 코드 스니펫은 3자리 숫자와 대체 값 --를 사용하여 심박수 업데이트를 표시하는 방법을 보여줍니다.

override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(
                Timeline.fromLayoutElement(
                    Text.Builder(
                        this,
                        TypeBuilders.StringProp.Builder("--")
                            .setDynamicValue(
                                PlatformHealthSources.heartRateBpm()
                                    .format()
                                    .concat(DynamicBuilders.DynamicString.constant(" bpm"))
                            )
                            .build(),
                        TypeBuilders.StringLayoutConstraint.Builder("000").build(),
                    )
                        .build()
                )
            )
            .build()
    )

하나의 카드에서 적은 수의 표현식 사용

Wear OS는 하나의 카드에 포함할 수 있는 표현식의 수에 제한을 둡니다. 카드에 동적 표현식이 너무 많으면 동적 값이 무시되고 개발자가 각 동적 속성 유형에 제공한 정적 값으로 대체됩니다.

동적 데이터를 상태 객체로 통합

데이터 소스의 최신 업데이트 집합을 상태로 통합하고 값 렌더링을 위해 이 값을 카드에 전달할 수 있습니다.

카드에서 상태 정보를 사용하려면 다음 단계를 따릅니다.

  1. 카드 상태의 여러 값을 나타내는 키 집합을 설정합니다. 이 예시에서는 물 섭취 키와 메모 키를 만듭니다.

    Kotlin

    companion object {
        val KEY_WATER_INTAKE = AppDataKey<DynamicInt32>("water_intake")
        val KEY_NOTE = AppDataKey<DynamicString>("note")
    }

    Java

    private static final AppDataKey<DynamicInt32> KEY_WATER_INTAKE =
        new AppDataKey<DynamicInt32>("water_intake");
    private static final AppDataKey<DynamicString> KEY_NOTE =
        new AppDataKey<DynamicString>("note");
  2. onTileRequest() 구현에서 setState()를 호출하고 각 키에서 특정 동적 데이터 값으로의 초기 매핑을 설정합니다.

    Kotlin

    override fun onTileRequest(requestParams: TileRequest):
            ListenableFuture<Tile> {
        val state = State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build()
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        )

    Java

    @Override
    protected ListenableFuture<Tile> onTileRequest(
                ListenableFuture<Tile> {
        State state = new State.Builder()
            .addKeyToValueMapping(KEY_WATER_INTAKE,
                DynamicDataBuilders.DynamicDataValue.fromInt(200))
            .addKeyToValueMapping(KEY_NOTE,
                DynamicDataBuilders.DynamicDataValue.fromString("Note about day"))
        .build();
        // ...
    
        return Futures.immediateFuture(Tile.Builder()
            // Set resources, timeline, and other tile properties.
            .setState(state)
            .build()
        );
    }
  3. 레이아웃을 만들 때는 상태의 데이터를 표시할 위치에서 Dynamic* 유형 객체를 사용합니다. animate()를 호출하여 이전 값에서 현재 값으로의 애니메이션을 보여줄 수도 있습니다.

    Kotlin

    DynamicInt32.from(KEY_WATER_INTAKE).animate()

    Java

    DynamicInt32.from(KEY_WATER_INTAKE).animate();
  4. 필요한 경우 상태를 새 값으로 업데이트할 수도 있습니다. 이는 카드의 LoadAction에 포함할 수 있습니다.

    이 예시에서는 물 섭취 값이 400으로 업데이트됩니다.

    Kotlin

    val loadAction = LoadAction.Builder()
        .setRequestState(
            State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                )
                .build()
        )
        .build()

    자바

    LoadAction loadAction = new LoadAction.Builder()
        .setRequestState(
            new State.Builder()
                .addKeyToValueMapping(
                    KEY_WATER_INTAKE,
                    DynamicDataBuilders.DynamicDataValue.fromInt(400)
                ).build()
        ).build();