Trên thiết bị Wear OS, thẻ thông tin được hiển thị bằng hai thành phần chính có phiên bản độc lập. Để đảm bảo thẻ thông tin ứng dụng hoạt động chính xác trên tất cả thiết bị, bạn cần hiểu rõ cấu trúc cơ bản này.
- Thư viện liên quan đến thẻ thông tin Jetpack: Các thư viện này (bao gồm cả Thẻ thông tin Wear và Wear ProtoLayout) được nhúng trong ứng dụng của bạn và bạn (với tư cách là nhà phát triển) sẽ kiểm soát các phiên bản của các thư viện đó. Ứng dụng của bạn sử dụng các thư viện này để tạo đối tượng
TileBuilder.Tile
(cấu trúc dữ liệu đại diện cho Thẻ thông tin) để phản hồi lệnh gọionTileRequest()
của hệ thống. - Trình kết xuất ProtoLayout: Thành phần hệ thống này chịu trách nhiệm kết xuất đối tượng
Tile
trên màn hình và xử lý các hoạt động tương tác của người dùng. Phiên bản trình kết xuất không do nhà phát triển ứng dụng kiểm soát và có thể khác nhau giữa các thiết bị, ngay cả những thiết bị có phần cứng giống hệt nhau.
Giao diện hoặc hành vi của Thẻ thông tin có thể khác nhau tuỳ thuộc vào cả phiên bản thư viện Thẻ thông tin Jetpack của ứng dụng và phiên bản Trình kết xuất bố cục nguyên mẫu trên thiết bị của người dùng. Ví dụ: một thiết bị có thể hỗ trợ tính năng xoay hoặc hiển thị dữ liệu nhịp tim, còn thiết bị khác thì không.
Tài liệu này giải thích cách đảm bảo ứng dụng của bạn tương thích với các phiên bản khác nhau của thư viện Thẻ thông tin và Trình kết xuất ProtoLayout, cũng như cách di chuyển sang các phiên bản thư viện Jetpack cao hơn.
Cân nhắc khả năng tương thích
Để tạo Thẻ thông tin hoạt động chính xác trên nhiều thiết bị, bạn nên cân nhắc những điều sau.
Phát hiện phiên bản trình kết xuất
- Sử dụng phương thức
getRendererSchemaVersion()
của đối tượngDeviceParameters
được truyền vào phương thức onTileRequest(). Phương thức này trả về số phiên bản chính và phụ của Trình kết xuất ProtoLayout trên thiết bị. - Sau đó, bạn có thể sử dụng logic có điều kiện trong quá trình triển khai
onTileRequest()
để điều chỉnh thiết kế hoặc hành vi của Thẻ thông tin dựa trên phiên bản trình kết xuất được phát hiện.- Ví dụ: nếu một ảnh động cụ thể không được hỗ trợ, bạn có thể hiển thị một hình ảnh tĩnh.
Chú thích @RequiresSchemaVersion
- Chú thích
@RequiresSchemaVersion
trên các phương thức ProtoLayout cho biết phiên bản giản đồ trình kết xuất tối thiểu cần thiết để phương thức đó hoạt động như đã ghi nhận (ví dụ).- Mặc dù việc gọi một phương thức yêu cầu phiên bản trình kết xuất cao hơn phiên bản có trên thiết bị sẽ không khiến ứng dụng của bạn gặp sự cố, nhưng điều này có thể dẫn đến việc nội dung không hiển thị hoặc tính năng bị bỏ qua.
Ví dụ
override fun onTileRequest(
requestParams: TileService.TileRequest
): ListenableFuture<Tile> {
val rendererVersion =
requestParams.deviceConfiguration.rendererSchemaVersion
val tile = Tile.Builder()
if (
rendererVersion.major > 1 ||
(rendererVersion.major == 1 && rendererVersion.minor >= 300)
) {
// Use a feature supported in renderer version 1.300 or later
tile.setTileTimeline(/* ... */ )
} else {
// Provide fallback content for older renderers
tile.setTileTimeline(/* ... */ )
}
return Futures.immediateFuture(tile.build())
}
Kiểm thử với nhiều phiên bản trình kết xuất
Để kiểm thử thẻ thông tin của bạn trên nhiều phiên bản trình kết xuất, hãy triển khai các thẻ thông tin đó cho nhiều phiên bản trình mô phỏng Wear OS. (Trên thiết bị thực, các bản cập nhật Trình kết xuất ProtoLayout sẽ do Cửa hàng Play hoặc bản cập nhật hệ thống phân phối. Không thể buộc cài đặt một phiên bản trình kết xuất cụ thể.)
Tính năng Xem trước thẻ thông tin của Android Studio sử dụng trình kết xuất được nhúng trong thư viện Jetpack ProtoLayout mà mã của bạn phụ thuộc vào. Vì vậy, một phương pháp khác là phụ thuộc vào các phiên bản thư viện Jetpack khác nhau khi kiểm thử thẻ thông tin.
Di chuyển sang Thẻ thông tin 1.5 / ProtoLayout 1.3 (Material 3 Expressive)
Cập nhật thư viện Thẻ thông tin Jetpack để tận dụng các tính năng nâng cao mới nhất, bao gồm cả các thay đổi về giao diện người dùng để Thẻ thông tin của bạn tích hợp liền mạch với hệ thống.
Jetpack Tiles 1.5 và Jetpack ProtoLayout 1.3 giới thiệu một số điểm cải tiến và thay đổi đáng chú ý. bao gồm:
- Một API giống như Compose để mô tả giao diện người dùng.
- Các thành phần Material 3 Expressive, bao gồm cả nút cạnh ôm sát dưới cùng và hỗ trợ hình ảnh nâng cao: ảnh động Lottie, nhiều loại chuyển màu hơn và kiểu đường vòng cung mới. – Lưu ý: bạn cũng có thể sử dụng một số tính năng này mà không cần di chuyển sang API mới.
Đề xuất
- Di chuyển đồng thời tất cả thẻ thông tin. Tránh kết hợp các phiên bản thẻ thông tin trong ứng dụng. Mặc dù các thành phần Material 3 nằm trong một cấu phần phần mềm riêng biệt (
androidx.wear.protolayout:protolayout-material3
) – giúp bạn có thể sử dụng cả Thẻ thông tin M2.5 và M3 trong cùng một ứng dụng – nhưng bạn không nên sử dụng phương pháp này trừ khi thực sự cần thiết (ví dụ: nếu ứng dụng của bạn có một số lượng lớn thẻ thông tin không thể di chuyển cùng một lúc). - Áp dụng hướng dẫn về trải nghiệm người dùng của Thẻ thông tin. Do bản chất của thẻ thông tin là có cấu trúc và mẫu cao, hãy sử dụng các thiết kế trong các mẫu hiện có làm điểm xuất phát cho thiết kế của riêng bạn.
- Kiểm thử trên nhiều kích thước màn hình và phông chữ. Thẻ thông tin thường chứa nhiều thông tin, khiến văn bản (đặc biệt là khi đặt trên các nút) dễ bị tràn và cắt bớt. Để giảm thiểu điều này, hãy sử dụng các thành phần được tạo sẵn và tránh tuỳ chỉnh quá mức. Kiểm thử bằng tính năng xem trước thẻ thông tin của Android Studio cũng như trên nhiều thiết bị thực.
Quy trình di chuyển
Cập nhật phần phụ thuộc
Trước tiên, hãy cập nhật tệp build.gradle.kts
. Cập nhật các phiên bản và thay đổi phần phụ thuộc protolayout-material
thành protolayout-material3
, như minh hoạ:
// In build.gradle.kts
//val tilesVersion = "1.4.1"
//val protoLayoutVersion = "1.2.1"
// Use these versions for M3.
val tilesVersion = "1.5.0-rc01"
val protoLayoutVersion = "1.3.0-rc01"
dependencies {
// Use to implement support for wear tiles
implementation("androidx.wear.tiles:tiles:$tilesVersion")
// Use to utilize standard components and layouts in your tiles
implementation("androidx.wear.protolayout:protolayout:$protoLayoutVersion")
// Use to utilize components and layouts with Material Design in your tiles
// implementation("androidx.wear.protolayout:protolayout-material:$protoLayoutVersion")
implementation("androidx.wear.protolayout:protolayout-material3:$protoLayoutVersion")
// Use to include dynamic expressions in your tiles
implementation("androidx.wear.protolayout:protolayout-expression:$protoLayoutVersion")
// Use to preview wear tiles in your own app
debugImplementation("androidx.wear.tiles:tiles-renderer:$tilesVersion")
// Use to fetch tiles from a tile provider in your tests
testImplementation("androidx.wear.tiles:tiles-testing:$tilesVersion")
}
TileService vẫn không thay đổi nhiều
Các thay đổi chính trong quá trình di chuyển này ảnh hưởng đến các thành phần trên giao diện người dùng. Do đó, việc triển khai TileService
, bao gồm mọi cơ chế tải tài nguyên, sẽ yêu cầu ít sửa đổi hoặc không sửa đổi gì.
Trường hợp ngoại lệ chính liên quan đến tính năng theo dõi hoạt động của thẻ thông tin: nếu ứng dụng của bạn sử dụng onTileEnterEvent()
hoặc onTileLeaveEvent()
, bạn nên chuyển sang onRecentInteractionEventsAsync()
. Kể từ API 36, các sự kiện này sẽ được phân thành lô.
Điều chỉnh mã tạo bố cục
Trong ProtoLayout 1.2 (M2.5), phương thức onTileRequest()
trả về một TileBuilders.Tile
. Đối tượng này chứa nhiều phần tử, bao gồm cả TimelineBuilders.Timeline
, lần lượt chứa LayoutElement
mô tả giao diện người dùng của thẻ thông tin.
Với ProtoLayout 1.3 (M3), mặc dù cấu trúc và luồng dữ liệu tổng thể không thay đổi, nhưng LayoutElement
hiện được tạo bằng cách sử dụng phương pháp lấy cảm hứng từ Compose với bố cục dựa trên khe đã xác định (từ trên xuống dưới) là titleSlot
(thường là cho tiêu đề hoặc tiêu đề chính), mainSlot
(cho nội dung cốt lõi) và bottomSlot
(thường là cho các thao tác như nút cạnh hoặc thông tin bổ sung như văn bản ngắn). Bố cục này được tạo bằng hàm primaryLayout()
.

So sánh các hàm bố cục M2.5 và M3
M2.5
fun myLayout(
context: Context,
deviceConfiguration: DeviceParametersBuilders.DeviceParameters
) =
PrimaryLayout.Builder(deviceConfiguration)
.setResponsiveContentInsetEnabled(true)
.setContent(
Text.Builder(context, "Hello World!")
.setTypography(Typography.TYPOGRAPHY_BODY1)
.setColor(argb(0xFFFFFFFF.toInt()))
.build()
)
.build()
M3
fun myLayout(
context: Context,
deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
) =
materialScope(context, deviceConfiguration) {
primaryLayout(mainSlot = { text("Hello, World!".layoutString) })
}
Để làm nổi bật những điểm khác biệt chính:
- Loại bỏ trình tạo. Mẫu trình tạo truyền thống cho các thành phần giao diện người dùng Material3 được thay thế bằng cú pháp khai báo hơn, lấy cảm hứng từ Compose. (Các thành phần không phải giao diện người dùng như Chuỗi/Màu sắc/Công cụ sửa đổi cũng nhận được trình bao bọc Kotlin mới.)
- Hàm bố cục và khởi chạy được chuẩn hoá. Bố cục M3 dựa vào các hàm khởi tạo và cấu trúc được chuẩn hoá:
materialScope()
vàprimaryLayout()
. Các hàm bắt buộc này khởi chạy môi trường M3 (thiết kế giao diện, phạm vi thành phần thông quamaterialScope
) và xác định bố cục dựa trên khe chính (thông quaprimaryLayout
). Cả hai đều phải được gọi chính xác một lần cho mỗi bố cục.
Giao diện
Màu
Một tính năng nổi bật của Material 3 Expressive là "thiết kế giao diện động": các thẻ thông tin bật tính năng này (bật theo mặc định) sẽ hiển thị trong giao diện do hệ thống cung cấp (khả năng sử dụng tuỳ thuộc vào thiết bị và cấu hình của người dùng).
Một thay đổi khác trong M3 là mở rộng số lượng mã thông báo màu, tăng từ 4 lên 29. Bạn có thể tìm thấy mã thông báo màu mới trong lớp ColorScheme
.
Kiểu chữ
Tương tự như M2.5, M3 phụ thuộc nhiều vào các hằng số cỡ chữ được xác định trước. Bạn không nên chỉ định trực tiếp cỡ chữ. Các hằng số này nằm trong lớp Typography
và cung cấp một phạm vi mở rộng hơn một chút về các tuỳ chọn biểu đạt.
Để biết thông tin đầy đủ, hãy tham khảo tài liệu về Kiểu chữ.
Hình dạng
Hầu hết các thành phần M3 có thể thay đổi theo kích thước của hình dạng cũng như màu sắc.
textButton
(trong mainSlot
) có hình dạng full
:

Cùng một textButton có hình dạng small
:

Thành phần
Các thành phần M3 linh hoạt và có thể định cấu hình hơn đáng kể so với các thành phần M2.5 tương đương. Trong khi M2.5 thường yêu cầu các thành phần riêng biệt cho nhiều cách xử lý hình ảnh, thì M3 thường sử dụng thành phần "cơ sở" tổng quát nhưng có khả năng định cấu hình cao với các giá trị mặc định phù hợp.
Nguyên tắc này áp dụng cho bố cục "gốc". Trong M2.5, đây là PrimaryLayout
hoặc EdgeContentLayout
. Trong M3, sau khi một MaterialScope
cấp cao nhất được thiết lập, hàm primaryLayout()
sẽ được gọi. Thao tác này trả về bố cục gốc trực tiếp (không cần trình tạo) và chấp nhận LayoutElements
cho một số "khe", chẳng hạn như titleSlot
, mainSlot
và bottomSlot
. Bạn có thể điền các khe này bằng các thành phần giao diện người dùng cụ thể (chẳng hạn như do text(), button() hoặc card() trả về) hoặc cấu trúc bố cục, chẳng hạn như Row
hoặc Column
từ LayoutElementBuilders
.
Giao diện là một điểm cải tiến chính khác của M3. Theo mặc định, các thành phần trên giao diện người dùng sẽ tự động tuân thủ các thông số kỹ thuật về kiểu M3 và hỗ trợ giao diện động.
M2.5 | M3 |
---|---|
Các thành phần tương tác | |
Button hoặc Chip |
|
Văn bản | |
Text |
text() |
Chỉ báo tiến trình | |
CircularProgressIndicator |
circularProgressIndicator() hoặc segmentedCircularProgressIndicator() |
Bố cục | |
PrimaryLayout hoặc EdgeContentLayout |
primaryLayout() |
— | buttonGroup() |
Hình ảnh | |
— | icon() , avatarImage() hoặc backgroundImage() |
Đối tượng sửa đổi
Trong M3, Modifiers
mà bạn dùng để trang trí hoặc mở rộng một thành phần sẽ giống với Compose hơn. Thay đổi này có thể giảm mã nguyên mẫu bằng cách tự động tạo các loại nội bộ thích hợp. (Thay đổi này không liên quan đến việc sử dụng các thành phần giao diện người dùng M3; nếu cần, bạn có thể sử dụng các đối tượng sửa đổi kiểu trình tạo từ ProtoLayout 1.2 với các thành phần giao diện người dùng M3 và ngược lại.)
M2.5
// A Builder-style modifier to set the opacity of an element to 0.5
fun myModifier(): ModifiersBuilders.Modifiers =
ModifiersBuilders.Modifiers.Builder()
.setOpacity(TypeBuilders.FloatProp.Builder(0.5F).build())
.build()
M3
// The equivalent Compose-like modifier is much simpler
fun myModifier(): LayoutModifier = LayoutModifier.opacity(0.5F)
Bạn có thể tạo đối tượng sửa đổi bằng cách sử dụng một trong hai kiểu API và bạn cũng có thể sử dụng hàm mở rộng toProtoLayoutModifiers()
để chuyển đổi LayoutModifier
thành ModifiersBuilders.Modifier
.
Hàm trợ giúp
Mặc dù ProtoLayout 1.3 cho phép biểu thị nhiều thành phần giao diện người dùng bằng cách sử dụng API lấy cảm hứng từ Compose, nhưng các phần tử bố cục cơ bản như hàng và cột từ LayoutElementBuilders
vẫn tiếp tục sử dụng mẫu trình tạo. Để thu hẹp khoảng cách về kiểu này và thúc đẩy tính nhất quán với các API thành phần M3 mới, hãy cân nhắc sử dụng các hàm trợ giúp.
Không có trình trợ giúp
primaryLayout(
mainSlot = {
LayoutElementBuilders.Column.Builder()
.setWidth(expand())
.setHeight(expand())
.addContent(text("A".layoutString))
.addContent(text("B".layoutString))
.addContent(text("C".layoutString))
.build()
}
)
Có trình trợ giúp
// Function literal with receiver helper function
fun column(builder: Column.Builder.() -> Unit) =
Column.Builder().apply(builder).build()
primaryLayout(
mainSlot = {
column {
setWidth(expand())
setHeight(expand())
addContent(text("A".layoutString))
addContent(text("B".layoutString))
addContent(text("C".layoutString))
}
}
)
Di chuyển sang Thẻ thông tin 1.2 / ProtoLayout 1.0
Kể từ phiên bản 1.2, hầu hết các API Bố cục thẻ thông tin đều nằm trong không gian tên androidx.wear.protolayout
. Để sử dụng các API mới nhất, hãy hoàn tất các bước di chuyển sau đây trong mã của bạn.
Cập nhật phần phụ thuộc
Trong tệp bản dựng của mô-đun ứng dụng, hãy thực hiện các thay đổi sau:
Groovy
// Removeimplementation 'androidx.wear.tiles:tiles-material:version'// Include additional dependencies implementation "androidx.wear.protolayout:protolayout:1.2.1" implementation "androidx.wear.protolayout:protolayout-material:1.2.1" implementation "androidx.wear.protolayout:protolayout-expression:1.2.1" // Update implementation "androidx.wear.tiles:tiles:1.4.1"
Kotlin
// Removeimplementation("androidx.wear.tiles:tiles-material:version")// Include additional dependencies implementation("androidx.wear.protolayout:protolayout:1.2.1") implementation("androidx.wear.protolayout:protolayout-material:1.2.1") implementation("androidx.wear.protolayout:protolayout-expression:1.2.1") // Update implementation("androidx.wear.tiles:tiles:1.4.1")
Cập nhật không gian tên
Trong các tệp mã dựa trên Kotlin và Java của ứng dụng, hãy cập nhật như sau. Ngoài ra, bạn có thể thực thi tập lệnh đổi tên không gian tên này.
- Thay thế tất cả các lệnh nhập
androidx.wear.tiles.material.*
bằngandroidx.wear.protolayout.material.*
. Bạn cũng cần hoàn tất bước này cho thư việnandroidx.wear.tiles.material.layouts
. Thay thế hầu hết các lệnh nhập
androidx.wear.tiles.*
khác bằngandroidx.wear.protolayout.*
.Các lệnh nhập cho
androidx.wear.tiles.EventBuilders
,androidx.wear.tiles.RequestBuilders
,androidx.wear.tiles.TileBuilders
vàandroidx.wear.tiles.TileService
sẽ giữ nguyên.Đổi tên một vài phương thức không dùng nữa trong các lớp TileService và TileBuilder:
TileBuilders
:getTimeline()
thànhgetTileTimeline()
vàsetTimeline()
thànhsetTileTimeline()
TileService
:onResourcesRequest()
thànhonTileResourcesRequest()
RequestBuilders.TileRequest
:getDeviceParameters()
thànhgetDeviceConfiguration()
,setDeviceParameters()
thànhsetDeviceConfiguration()
,getState()
thànhgetCurrentState()
vàsetState()
thànhsetCurrentState()