Kể từ Thẻ thông tin 1.2, bạn có thể truyền trực tuyến nội dung cập nhật dữ liệu nền tảng bằng cách sử dụng biểu thức động. Sau đó, bạn có thể liên kết các nội dung cập nhật này với ảnh động trong thẻ thông tin của mình. Ứng dụng của bạn sẽ nhận được nội dung cập nhật cho giá trị này mỗi giây.
Khi sử dụng biểu thức động, bạn không cần làm mới toàn bộ thẻ thông tin khi nội dung của thẻ thay đổi. Để đem lại trải nghiệm hấp dẫn hơn trong các thẻ thông tin của bạn, hãy tạo ảnh động cho các đối tượng động đó.
Liên kết biểu thức động với nguồn dữ liệu
Không gian tên androidx.wear.protolayout
và androidx.wear.protolayout.material
chứa nhiều lớp có các trường chấp nhận biểu thức động.
Sau đây là một số ví dụ:
- Một số giá trị độ dài, trong đó có độ dài của đối tượng
Arc
và độ dài của đối tượngCircularProgressIndicator
. - Bất kỳ màu nào, chẳng hạn như màu cho nội dung của đối tượng
Button
. - Nhiều giá trị chuỗi, trong đó có nội dung của đối tượng
Text
, nội dung của đối tượngLayoutElementsBuilders.Text
và phần mô tả nội dung của đối tượngCircularProgressIndicator
.
Để dùng biểu thức động làm giá trị có thể có cho một phần tử trong thẻ thông tin của bạn, hãy sử dụng loại thuộc tính động *Prop
tương ứng của phần tử đó và chuyển nguồn dữ liệu vào phương thức setDynamicValue()
của lớp trình tạo của loại thuộc tính động.
Thẻ thông tin hỗ trợ các loại thuộc tính động sau đây:
- Đối với các kích thước tuyến tính, được đo bằng pixel và không phụ thuộc vào màn hình, hãy sử dụng
DimensionBuilders.DpProp
. - Đối với các kích thước góc, được đo bằng độ, hãy sử dụng
DimensionBuilders.DegreesProp
. - Đối với các giá trị chuỗi, hãy sử dụng
TypeBuilders.StringProp
. - Đối với các giá trị màu, hãy sử dụng
ColorBuilders.ColorProp
. - Đối với các giá trị dấu phẩy động, hãy sử dụng
TypeBuilders.FloatProp
.
Khi dùng một biểu thức động ảnh hưởng đến kích thước thực (bất kỳ giá trị nào trong thẻ thông tin ngoại trừ giá trị màu), bạn còn phải chỉ định một tập hợp các điều kiện ràng buộc có liên quan, chẳng hạn như định dạng chuỗi. Những điều kiện ràng buộc này cho phép trình kết xuất hệ thống xác định khoảng không gian tối đa mà một giá trị có thể chiếm trong thẻ thông tin của bạn. Thông thường, bạn chỉ định các điều kiện ràng buộc này ở cấp phần tử, chứ không phải ở cấp biểu thức động, bằng cách gọi một phương thức bắt đầu bằng setLayoutConstraintsForDynamic*
.
Đoạn mã sau đây chỉ ra cách hiện nội dung cập nhật nhịp tim bằng 3 chữ số, với giá trị dự phòng là --
:
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() ); }
Dùng ít biểu thức trong một thẻ thông tin
Wear OS đặt ra giới hạn cho số lượng biểu thức mà một thẻ thông tin có thể có. Nếu một thẻ thông tin có tổng cộng quá nhiều biểu thức động, thì các giá trị động sẽ bị bỏ qua và hệ thống sẽ chuyển về các giá trị tĩnh mà bạn cung cấp cho các loại thuộc tính động tương ứng.
Bạn có thể yên tâm thêm tập hợp biểu thức sau đây vào một thẻ thông tin vì tổng cộng không có quá nhiều biểu thức. Do đó, thẻ thông tin sẽ hoạt động chính xác:
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");
Tuy nhiên, thẻ thông tin sau có thể có quá nhiều biểu thức:
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) ); }
Hợp nhất dữ liệu động thành một đối tượng trạng thái
Bạn có thể hợp nhất tập hợp nội dung cập nhật mới nhất từ nguồn dữ liệu thành đối tượng trạng thái mà bạn sẽ chuyển vào thẻ thông tin của mình để hiển thị giá trị.
Để dùng thông tin trạng thái trong thẻ thông tin của bạn, hãy hoàn tất các bước sau:
Thiết lập một tập hợp khoá đại diện cho các giá trị khác nhau của trạng thái thẻ thông tin. Sau đây là ví dụ về cách tạo khoá cho lượng nước uống và ghi chú:
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");
Trong quá trình triển khai
onTileRequest()
, hãy gọisetState()
và thiết lập mối liên kết ban đầu từ mỗi khoá đến một giá trị dữ liệu động cụ thể: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() ); }
Khi bạn tạo bố cục, ở vị trí mà bạn muốn hiện dữ liệu này từ trạng thái, hãy sử dụng một đối tượng loại
Dynamic*
. Bạn cũng có thể gọianimate()
để hiện một ảnh động từ giá trị trước đó đến giá trị hiện tại:Kotlin
DynamicInt32.from(KEY_WATER_INTAKE).animate()
Java
DynamicInt32.from(KEY_WATER_INTAKE).animate();
Khi cần, bạn cũng có thể cập nhật trạng thái bằng các giá trị mới. Đây có thể là một phần của
LoadAction
của thẻ thông tin.Trong ví dụ sau, giá trị lượng nước uống được cập nhật thành
400
:Kotlin
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400))
Java
state.addKeyToValueMapping(KEY_WATER_INTAKE, DynamicDataBuilders.DynamicDataValue.fromInt(400));
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Di chuyển sang không gian tên ProtoLayout
- Làm quen với thẻ thông tin
- Những điểm khác cần cân nhắc