Tiles 1.2부터는 동적 표현식을 사용하여 플랫폼 데이터 업데이트를 스트리밍할 수 있습니다. 그런 다음 이러한 업데이트를 카드의 애니메이션에 연결할 수 있습니다. 앱에는 1초에 한 번 이 값의 업데이트가 제공됩니다.
동적 표현식을 사용하면 콘텐츠가 변경되어도 카드 전체를 새로고침할 필요가 없습니다. 카드에서 보다 시선을 사로잡는 경험을 만들려면 이러한 동적 객체에 애니메이션을 적용하세요.
동적 표현식을 데이터 소스에 연결
androidx.wear.protolayout
및 androidx.wear.protolayout.material
네임스페이스에는 필드에서 동적 표현식을 받는 클래스가 여럿 포함되어 있습니다.
몇 가지 예는 다음과 같습니다.
- 몇몇 길이 값(예:
Arc
객체의 길이,CircularProgressIndicator
객체의 길이) - 모든 색상(예:
Button
객체의 콘텐츠 색상) - 몇몇 문자열 값(예:
Text
객체의 콘텐츠,LayoutElementsBuilders.Text
객체의 콘텐츠,CircularProgressIndicator
객체의 콘텐츠 설명)
카드에 포함된 요소의 한 가지 가능한 값으로 동적 표현식을 사용하려면, 요소의 대응되는 *Prop
동적 속성 유형을 사용하고 동적 속성 유형의 빌더 클래스의 setDynamicValue()
메서드에 데이터 소스를 전달합니다.
카드는 다음과 같은 동적 속성 유형을 지원합니다.
- 디스플레이 독립 픽셀로 측정되는 선형 크기에는
DimensionBuilders.DpProp
을 사용합니다. - 각도로 측정되는 각도 데이터에는
DimensionBuilders.DegreesProp
을 사용합니다. - 문자열 값에는
TypeBuilders.StringProp
을 사용합니다. - 색상 값에는
ColorBuilders.ColorProp
을 사용합니다. - 부동 소수점 값에는
TypeBuilders.FloatProp
을 사용합니다.
실제 크기(색상을 제외한 카드의 모든 값)에 영향을 주는 동적 표현식을 사용할 때는 문자열 형식과 같은 관련 제약 조건도 지정해야 합니다. 이러한 제약 조건을 사용하면 시스템 렌더기가 카드 내에서 값이 차지할 수 있는 최대 공간을 확인할 수 있습니다. 일반적으로 이러한 제약 조건은 setLayoutConstraintsForDynamic*
으로 시작하는 메서드를 호출하여 동적 표현식 수준이 아닌 요소 수준에서 지정해야 합니다.
다음 코드 스니펫은 3자리 숫자와 대체 값 --
를 사용하여 심박수 업데이트를 표시하는 방법을 보여줍니다.
Kotlin
import androidx.wear.protolayout.material.Text public 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(), StringLayoutConstraint.Builder("000") .build() ).build() ) ).build() )
Java
import androidx.wear.protolayout.material.Text; @Override protected ListenableFuture<Tile> onTileRequest( @NonNull TileRequest requestParams ) { return Futures.immediateFuture(new Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes .setTileTimeline(Timeline.fromLayoutElement( new Text.Builder( this, new TypeBuilders.StringProp.Builder("--") .setDynamicValue(PlatformHealthSources.heartRateBpm() .format() .concat(DynamicBuilders.DynamicString.constant(" bpm"))) .build(), new StringLayoutConstraint.Builder("000") .build() ).build()) ).build() ); }
하나의 카드에서 적은 수의 표현식 사용
Wear OS는 하나의 카드에 포함할 수 있는 표현식의 수에 제한을 둡니다. 카드에 동적 표현식이 너무 많으면 동적 값이 무시되고 개발자가 각 동적 속성 유형에 제공한 정적 값으로 대체됩니다.
아래에서는 표현식의 개수가 그다지 많지 않으므로 안심하고 카드에 다음 표현식 세트를 추가할 수 있습니다. 따라서 카드가 올바르게 동작합니다.
Kotlin
val personHealthInfo = DynamicString.constant("This person has walked ") .concat(PlatformHealthSources.dailySteps() .div(1000) .format()) .concat("thousands of steps and has a current heart rate ") .concat(PlatformHealthSources.heartRateBpm() .format()) .concat(" beats per minute")
Java
DynamicString personHealthInfo = DynamicString.constant("This person has walked ") .concat(PlatformHealthSources.dailySteps() .div(1000) .format()) .concat("thousands of steps and has a current heart rate ") .concat(PlatformHealthSources.heartRateBpm() .format()) .concat(" beats per minute");
하지만 이 카드에는 표현식이 너무 많습니다.
Kotlin
// Note that this template is applied as many times as the loop iterates. // The system doesn't reuse dynamic expressions. val dynamicStringTemplate = PlatformHealthSources.dailySteps() .div(1000) .format() for (person in people) { // SomeProperty .setDynamicValue( DynamicBuilders.DynamicString.constant("Steps for ") .concat(person) .concat(" are ") .concat(dynamicStringTemplate) ) }
Java
// Note that this template is applied as many times as the loop iterates. // The system doesn't reuse dynamic expressions. DynamicString dynamicStringTemplate = PlatformHealthSources.dailySteps() .div(1000) .format(); for (int i = 0; i < people.size(); i++) { // SomeProperty .setDynamicValue( DynamicBuilders.DynamicString.constant("Steps for ") .concat(people[i]) .concat(" are ") .concat(dynamicStringTemplate) ); }
동적 데이터를 상태 객체로 통합
데이터 소스의 최신 업데이트 집합을 상태로 통합하고 값 렌더링을 위해 이 값을 카드에 전달할 수 있습니다.
카드에서 상태 정보를 사용하려면 다음 단계를 따릅니다.
카드 상태의 여러 값을 나타내는 키 집합을 설정합니다. 이 예시에서는 물 섭취 키와 메모 키를 만듭니다.
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");
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() ); }
레이아웃을 만들 때는 상태의 데이터를 표시할 위치에서
Dynamic*
유형 객체를 사용합니다.animate()
를 호출하여 이전 값에서 현재 값으로의 애니메이션을 보여줄 수도 있습니다.Kotlin
DynamicInt32.from(KEY_WATER_INTAKE).animate()
Java
DynamicInt32.from(KEY_WATER_INTAKE).animate();
필요한 경우 상태를 새 값으로 업데이트할 수도 있습니다. 이는 카드의
LoadAction
에 포함할 수 있습니다.이 예시에서는 물 섭취 값이
400
으로 업데이트됩니다.Kotlin
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400))
자바
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400));
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- ProtoLayout 네임스페이스로 이전
- 카드 시작하기
- 기타 고려사항