Làm quen với thẻ thông tin


Để bắt đầu cung cấp thẻ thông tin từ ứng dụng, hãy đưa các phần phụ thuộc sau đây vào tệp build.gradle của ứng dụng.

Groovy

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.4.1"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.2.1"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.2.1"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.2.1"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.4.1"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.4.1"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.4.1")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.2.1")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.2.1")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.2.1")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.4.1")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.4.1")
}

Khái niệm chính

Thẻ thông tin không được tạo theo cách tương tự như ứng dụng Android và sử dụng các khái niệm khác nhau:

  • Mẫu bố cục: Xác định cách sắp xếp tổng thể các thành phần hình ảnh trên màn hình. Bạn có thể thực hiện việc này bằng hàm primaryLayout().
  • Thành phần bố cục: Biểu thị một thành phần đồ hoạ riêng lẻ, chẳng hạn như nút hoặc thẻ, hoặc một số thành phần như vậy được nhóm lại với nhau bằng cột, buttonGroup hoặc tương tự. Các thành phần này được nhúng trong một mẫu bố cục.
  • Tài nguyên: Các đối tượng ResourceBuilders.Resources bao gồm một bản đồ của các cặp khoá-giá trị của tài nguyên Android (hình ảnh) cần thiết để hiển thị bố cục và một phiên bản.
  • Dòng thời gian: Đối tượng TimelineBuilders.Timeline là một danh sách gồm một hoặc nhiều thực thể của một đối tượng bố cục. Bạn có thể cung cấp nhiều cơ chế và biểu thức để cho biết thời điểm trình kết xuất nên chuyển đổi từ đối tượng bố cục này sang đối tượng bố cục khác, chẳng hạn như để ngừng hiển thị bố cục tại một thời điểm cụ thể.
  • Trạng thái: Cấu trúc dữ liệu thuộc loại StateBuilders.State được truyền giữa thẻ thông tin và ứng dụng để cho phép hai thành phần này giao tiếp với nhau. Ví dụ: nếu người dùng nhấn vào một nút trên thẻ thông tin, thì trạng thái sẽ chứa mã nhận dạng của nút đó. Bạn cũng có thể trao đổi các loại dữ liệu bằng cách sử dụng bản đồ.
  • Thẻ thông tin: Đối tượng TileBuilders.Tile đại diện cho một thẻ thông tin, bao gồm tiến trình, mã phiên bản tài nguyên, khoảng thời gian làm mớitrạng thái.
  • Protolayout: Thuật ngữ này xuất hiện trong tên của nhiều lớp liên quan đến thẻ thông tin và đề cập đến thư viện Wear OS Protolayout, một thư viện đồ hoạ được sử dụng trên nhiều nền tảng Wear OS.

Tạo ô

Để cung cấp thẻ thông tin từ ứng dụng, hãy triển khai một dịch vụ thuộc loại TileService và đăng ký dịch vụ đó trong tệp kê khai. Từ đó, hệ thống yêu cầu các thẻ thông tin cần thiết trong các lệnh gọi đến onTileRequest()tài nguyên trong các lệnh gọi đến onTileResourcesRequest().

class MyTileService : TileService() {

    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
        Futures.immediateFuture(
            Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setTileTimeline(
                    Timeline.fromLayoutElement(
                        materialScope(this, requestParams.deviceConfiguration) {
                            primaryLayout(
                                mainSlot = {
                                    text("Hello, World!".layoutString, typography = BODY_LARGE)
                                }
                            )
                        }
                    )
                )
                .build()
        )

    override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
        Futures.immediateFuture(
            Resources.Builder().setVersion(RESOURCES_VERSION).build()
        )
}

Tiếp theo, hãy thêm một dịch vụ bên trong thẻ <application> của tệp AndroidManifest.xml.

<service
    android:name=".snippets.m3.tile.MyTileService"
    android:label="@string/tile_label"
    android:description="@string/tile_description"
    android:icon="@mipmap/ic_launcher"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

Bộ lọc quyền và ý định sẽ đăng ký dịch vụ này làm trình cung cấp thẻ thông tin.

Người dùng sẽ thấy biểu tượng, nhãn, nội dung mô tả và tài nguyên xem trước khi định cấu hình thẻ thông tin trên điện thoại hoặc đồng hồ. Xin lưu ý rằng tài nguyên xem trước hỗ trợ tất cả bộ hạn định tài nguyên chuẩn của Android, vì vậy, bạn có thể thay đổi bản xem trước theo các yếu tố như kích thước màn hình và ngôn ngữ thiết bị. Hãy xem danh sách kiểm tra bản xem trước để biết thêm các đề xuất.

Triển khai ứng dụng và thêm Thẻ thông tin vào Băng chuyền thẻ thông tin (cũng có cách xem trước Thẻ thông tin phù hợp hơn với nhà phát triển, nhưng hiện tại, bạn chỉ cần làm theo cách thủ công).

Thẻ thông tin &quot;Hello World&quot; (Xin chào thế giới).
Hình 1. Thẻ thông tin "Hello World" (Xin chào thế giới).

Để xem ví dụ đầy đủ, hãy xem mã mẫu trên GitHub hoặc lớp học lập trình.

Tạo giao diện người dùng cho thẻ thông tin

Các thành phần giao diện người dùng Material 3 Expressive được tạo bằng cách sử dụng phương pháp có cấu trúc dựa trên mẫu trình tạo an toàn về loại của Kotlin.

Bố cục

Để tạo bố cục, hãy làm như sau:

  1. Bắt đầu phạm vi Material Design: Gọi hàm materialScope(), cung cấp contextdeviceConfiguration bắt buộc. Bạn có thể đưa vào các tham số không bắt buộc, chẳng hạn như allowDynamicThemedefaultColorScheme. allowDynamicThemetrue theo mặc định và defaultColorScheme đại diện cho ColorScheme được dùng khi không có màu động, chẳng hạn như khi người dùng đã tắt tính năng này hoặc khi thiết bị không hỗ trợ tính năng này hoặc allowDynamicThemefalse).

  2. Xây dựng giao diện người dùng trong phạm vi: Tất cả thành phần giao diện người dùng cho một bố cục Thẻ thông tin nhất định phải được xác định trong lambda của một lệnh gọi materialScope() cấp cao nhất. Các hàm thành phần này, chẳng hạn như primaryLayout()textEdgeButton(), là các hàm mở rộng trên MaterialScope và chỉ có sẵn khi được gọi trong phạm vi trình thu nhận này.

    materialScope(
        context = context,
        deviceConfiguration = requestParams.deviceConfiguration, // requestParams is passed to onTileRequest
        defaultColorScheme = myFallbackColorScheme
    ) {
        // inside the MaterialScope, you can call functions like primaryLayout()
        primaryLayout(
            titleSlot = { text(text = "Title".layoutString) },
            mainSlot = { text(text = "Main Content".layoutString) },
            bottomSlot = { textEdgeButton(text = "Action".layoutString) }
        )
    }
    

Máy đánh bạc

Trong M3, bố cục thẻ thông tin sử dụng phương pháp lấy cảm hứng từ Compose, trong đó tận dụng 3 khe riêng biệt. Các lớp này chạy từ trên xuống dưới, bao gồm:

  1. titleSlot, thường là cho tiêu đề hoặc tiêu đề chính.
  2. mainSlot, dành cho nội dung cốt lõi.
  3. bottomSlot, thường được dùng cho các thao tác hoặc thông tin bổ sung. Đây cũng là nơi nút cạnh xuất hiện.
Bố cục Thẻ thông tin hiển thị titleSlot, mainSlot và bottomSlot
Hình 2. titleSlot, mainSlot và bottomSlot.

Nội dung của mỗi khung là như sau:

  • titleSlot (không bắt buộc): Thông thường là một vài từ do text() tạo.
  • mainSlot (bắt buộc): Các thành phần được sắp xếp thành các cấu trúc như hàng, cộtnhóm nút. Các thành phần này cũng có thể được nhúng đệ quy vào nhau; ví dụ: một cột có thể chứa các hàng.
  • bottomSlot (không bắt buộc): Thường được điền bằng nút viền hoặc nhãn văn bản.

Vì không thể cuộn thẻ thông tin nên không có thành phần nào để phân trang, cuộn hoặc xử lý danh sách dài nội dung. Hãy cẩn thận để nội dung vẫn hiển thị khi kích thước phông chữ tăng lên hoặc văn bản dài hơn do quá trình dịch.

Thành phần giao diện người dùng

Thư viện protolayout-material3 cung cấp một lượng lớn thành phần được thiết kế theo thông số kỹ thuật của Material 3 Expressive và các đề xuất về giao diện người dùng.

Nút

  • textButton(): nút có một khe duy nhất cho nội dung văn bản (ngắn)
  • iconButton(): nút có một khe duy nhất để biểu thị một biểu tượng
  • avatarButton(): nút hình đại diện hình viên nang cung cấp tối đa 3 khe để lấy nội dung đại diện cho nhãn và nhãn phụ xếp chồng theo chiều dọc, cùng với một hình ảnh (hình đại diện) bên cạnh
  • imageButton(): nút hình ảnh có thể nhấp không cung cấp thêm khe, chỉ có hình ảnh (ví dụ: backgroundImage làm nền)
  • compactButton(): nút thu gọn cung cấp tối đa 2 khe để lấy nội dung được xếp chồng theo chiều ngang đại diện cho một biểu tượng và văn bản bên cạnh
  • button(): nút hình viên nang cung cấp tối đa 3 khe để lấy nội dung đại diện cho nhãn chính và nhãn phụ được xếp chồng theo chiều dọc, cùng với một biểu tượng bên cạnh

Nút cạnh

  • iconEdgeButton(): nút cạnh cung cấp một khe duy nhất để chụp biểu tượng hoặc nội dung nhỏ, tròn tương tự
  • textEdgeButton(): nút cạnh cung cấp một khe duy nhất để chụp văn bản hoặc nội dung dài và rộng tương tự

Thẻ

  • titleCard(): thẻ tiêu đề cung cấp từ một đến ba vị trí, thường dựa trên văn bản
  • appCard(): thẻ ứng dụng cung cấp tối đa 5 khe, thường dựa trên văn bản
  • textDataCard(): thẻ dữ liệu cung cấp tối đa 3 khe xếp chồng theo chiều dọc, thường dựa trên văn bản hoặc số
  • iconDataCard(): thẻ dữ liệu cung cấp tối đa 3 khe xếp chồng theo chiều dọc, thường là dựa trên văn bản hoặc số, có biểu tượng
  • graphicDataCard(): thẻ dữ liệu đồ hoạ cung cấp một khe cho dữ liệu đồ hoạ, chẳng hạn như chỉ báo tiến trình và tối đa hai khe xếp chồng theo chiều dọc, thường là để mô tả văn bản

Chỉ báo tiến trình

  • circularProgressIndicator(): cho biết tiến trình hướng tới một mục tiêu bằng cách sử dụng phần tử hình tròn
  • segmentedCircularProgressIndicator(): cho biết tiến trình hướng tới một mục tiêu bằng cách sử dụng một phần tử hình tròn có các giai đoạn riêng biệt

Nhóm các phần tử bố cục

  • buttonGroup(): bố cục thành phần đặt các phần tử con theo trình tự ngang
  • primaryLayout(): bố cục toàn màn hình thể hiện kiểu bố cục M3 được đề xuất, có khả năng thích ứng và xử lý vị trí của các phần tử, cùng với lề và khoảng đệm được đề xuất được áp dụng

Giao diện

Trong Material 3 Expressive, hệ thống màu được xác định bằng 29 vai trò màu tiêu chuẩn, được sắp xếp thành 6 nhóm: chính, phụ, thứ ba, lỗi, bề mặt và đường viền.

Hệ thống màu sắc biểu cảm của Material 3
Hình 3. Hệ thống màu sắc biểu cảm của Material 3.

ColorScheme liên kết từng vai trò trong số 29 vai trò này với một màu tương ứng và vì là một phần của MaterialScope và các thành phần phải được tạo trong đó, nên các thành phần này sẽ tự động lấy màu từ bảng phối màu. Phương pháp này cho phép tất cả các thành phần giao diện người dùng tự động tuân thủ các tiêu chuẩn Material Design.

Để cho phép người dùng chọn giữa bảng phối màu mà bạn xác định (chẳng hạn như bảng phối màu phản ánh màu sắc thương hiệu của bạn) và bảng phối màu do hệ thống cung cấp (có thể bắt nguồn từ mặt đồng hồ hiện tại của người dùng hoặc mặt đồng hồ do người dùng chọn), hãy khởi chạy MaterialScope như sau:

val myColorScheme =
    ColorScheme(
        primary = ...
        onPrimary = ...
        // 27 more
    )

materialScope(
  defaultColorScheme = myColorScheme
) {
  // If the user selects "no theme" in settings, myColorScheme is used.
  // Otherwise, the system-provided theme is used.
}

Để buộc thẻ thông tin xuất hiện trong bảng phối màu mà bạn cung cấp, hãy tắt tính năng hỗ trợ giao diện động bằng cách đặt allowDynamicTheme thành false:

materialScope(
  allowDynamicTheme = false,
  defaultColorScheme = myColorScheme
) {
  // myColorScheme is *always* used.
}

Màu

Mỗi thành phần riêng lẻ sử dụng một tập hợp con trong số 29 vai trò màu do ColorScheme xác định. Ví dụ: các nút sử dụng tối đa 4 màu, theo mặc định được lấy từ nhóm "chính" của ColorScheme đang hoạt động:

Mã thông báo thành phần ButtonColors Vai trò ColorScheme
containerColor chính
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (độ mờ 0,8)

Bạn có thể cần phải thay đổi mã hiệu màu mặc định cho các thành phần giao diện người dùng cụ thể. Ví dụ: bạn có thể muốn một textEdgeButton sử dụng màu từ nhóm "phụ" hoặc "tertiary" (phụ cấp) thay vì "primary" (chính) để nổi bật và tạo độ tương phản tốt hơn.

Bạn có thể tuỳ chỉnh màu sắc của thành phần theo một số cách:

  1. Sử dụng hàm trợ giúp cho các màu được xác định trước. Sử dụng các hàm trợ giúp như filledTonalButtonColors() để áp dụng các kiểu nút tiêu chuẩn cho Material 3 Expressive. Các hàm này tạo các thực thể ButtonColors được định cấu hình trước liên kết các kiểu phổ biến như tô màu, sắc độ hoặc đường viền với các vai trò thích hợp từ ColorScheme đang hoạt động trong MaterialScope. Điều này cho phép bạn áp dụng các kiểu nhất quán mà không cần xác định từng màu theo cách thủ công cho các loại nút phổ biến.

    textEdgeButton(
        colors = filledButtonColors() // default
        /* OR colors = filledTonalButtonColors() */
        /* OR colors = filledVariantButtonColors() */
        // ... other parameters
    )
    

    Đối với thẻ, hãy sử dụng nhóm hàm filledCardColors() tương đương.

    Bạn cũng có thể sửa đổi đối tượng ButtonColors do các hàm trợ giúp trả về bằng cách sử dụng phương thức copy() của các hàm đó nếu bạn chỉ cần thay đổi một hoặc hai mã thông báo:

    textEdgeButton(
        colors =
            filledButtonColors()
                .copy(
                    containerColor = colorScheme.tertiary,
                    labelColor = colorScheme.onTertiary
                )
        // ... other parameters
    )
    
  2. Cung cấp rõ ràng các vai trò màu thay thế. Tạo đối tượng ButtonColors của riêng bạn rồi truyền đối tượng đó đến thành phần. Đối với thẻ, hãy sử dụng đối tượng CardColors tương đương.

    textEdgeButton(
        colors =
            ButtonColors(
                // the materialScope makes colorScheme available
                containerColor = colorScheme.secondary,
                iconColor = colorScheme.secondaryDim,
                labelColor = colorScheme.onSecondary,
                secondaryLabelColor = colorScheme.onSecondary
            )
        // ... other parameters
    )
    
  3. Chỉ định màu cố định (hãy thận trọng khi sử dụng). Mặc dù bạn thường nên chỉ định màu theo vai trò ngữ nghĩa (ví dụ: colorScheme.primary), bạn cũng có thể cung cấp giá trị màu trực tiếp. Bạn nên sử dụng phương pháp này một cách tiết kiệm vì nó có thể dẫn đến sự không nhất quán với giao diện tổng thể, đặc biệt là nếu giao diện thay đổi một cách linh động.

    textEdgeButton(
        colors = filledButtonColors().copy(
            containerColor = android.graphics.Color.RED.argb, // Using named colors
            labelColor = 0xFFFFFF00.argb // Using a hex code for yellow
        )
        // ... other parameters
    )
    

Kiểu chữ

Để tạo sự nhất quán về hình ảnh trên nền tảng Wear OS và tối ưu hoá hiệu suất, tất cả văn bản trên thẻ thông tin đều được hiển thị bằng phông chữ do hệ thống cung cấp. Tức là thẻ thông tin không hỗ trợ kiểu chữ tuỳ chỉnh. Trên Wear OS 6 trở lên, đây là phông chữ dành riêng cho OEM. Trong hầu hết các trường hợp, đó sẽ là phông chữ biến, mang lại trải nghiệm biểu đạt rõ ràng hơn và khả năng kiểm soát chi tiết hơn.

Để tạo kiểu văn bản, bạn thường sử dụng phương thức text() kết hợp với các hằng số kiểu chữ. Thành phần này cho phép bạn sử dụng các vai trò kiểu chữ được xác định trước trong Material 3 Expressive, giúp thẻ thông tin tuân thủ các phương pháp hay nhất đã thiết lập về kiểu chữ để dễ đọc và phân cấp. Thư viện này cung cấp một bộ 18 hằng số kiểu chữ ngữ nghĩa, chẳng hạn như BODY_MEDIUM. Các hằng số này cũng ảnh hưởng đến các trục phông chữ ngoài kích thước.

text(
    text = "Hello, World!".layoutString,
    typography = BODY_MEDIUM,
)

Để có thêm quyền kiểm soát, bạn có thể cung cấp các chế độ cài đặt bổ sung. Trên Wear OS 6 trở lên, có thể bạn sẽ sử dụng phông chữ biến thể. Bạn có thể sửa đổi phông chữ này theo các trục in nghiêng, độ đậm, chiều rộngđộ tròn. Bạn có thể kiểm soát các trục này bằng tham số settings:

text(
    text = "Hello, World".layoutString,
    italic = true,

    // Use elements defined in androidx.wear.protolayout.LayoutElementBuilders.FontSetting
    settings =
        listOf(weight(500), width(100F), roundness(100)),
)

Cuối cùng, nếu bạn cần kiểm soát kích thước hoặc khoảng cách giữa các chữ cái (không nên dùng), hãy sử dụng basicText() thay vì text() và tạo một giá trị cho thuộc tính fontStyle bằng fontStyle().

Hình dạng và lề

Bạn có thể thay đổi bán kính góc của hầu hết các thành phần bằng cách sử dụng thuộc tính shape. Các giá trị đến từ thuộc tính MaterialScope shapes:

textButton(
   height = expand(),
   width = expand(),
   shape = shapes.medium, // OR another value like shapes.full
   colors = filledVariantButtonColors(),
   labelContent = { text("Hello, World!".layoutString) },
)

Sau khi bạn thay đổi hình dạng của một thành phần, nếu bạn cho rằng thành phần đó để lại quá nhiều hoặc quá ít không gian xung quanh cạnh màn hình, hãy điều chỉnh lề bằng cách sử dụng tham số margin của primaryLayout():

primaryLayout(
    mainSlot = {
        textButton(
            shape = shapes.small,
            /* ... */
        )
    },
    // margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
    margins = MAX_PRIMARY_LAYOUT_MARGIN,
)

Vòng cung

Dưới đây là các vùng chứa con Arc được hỗ trợ:

  • ArcLine: hiển thị một đường cong xung quanh Vòng cung.
  • ArcText: hiển thị văn bản cong trong Vòng cung.
  • ArcAdapter: hiển thị một phần tử bố cục cơ bản trong vòng cung, được vẽ tại tiếp tuyến của vòng cung.

Để biết thêm thông tin, hãy xem tài liệu tham khảo cho từng loại phần tử.

Đối tượng sửa đổi

Bạn có thể tuỳ ý áp dụng các công cụ sửa đổi cho mỗi phần tử bố cục có sẵn. Hãy sử dụng các công cụ sửa đổi này cho những mục đích sau:

  • Thay đổi giao diện hình ảnh của bố cục. Ví dụ: thêm nền, đường viền hoặc khoảng đệm vào phần tử bố cục.
  • Thêm siêu dữ liệu về bố cục. Ví dụ: thêm một đối tượng sửa đổi ngữ nghĩa vào phần tử bố cục để sử dụng với trình đọc màn hình.
  • Thêm chức năng. Ví dụ: thêm vào phần tử bố cục một đối tượng sửa đổi có thể nhấp để thẻ thông tin có khả năng tương tác. Để biết thêm thông tin, hãy xem bài viết Tương tác với thẻ thông tin.

Ví dụ: chúng ta có thể tuỳ chỉnh giao diện và siêu dữ liệu mặc định của Image, như trong mã mẫu sau:

Kotlin

private fun myImage(): LayoutElement =
    Image.Builder()
        .setWidth(dp(24f))
        .setHeight(dp(24f))
        .setResourceId("image_id")
        .setModifiers(Modifiers.Builder()
            .setBackground(Background.Builder().setColor(argb(0xFFFF0000)).build())
            .setPadding(Padding.Builder().setStart(dp(12f)).build())
            .setSemantics(Semantics.builder()
                .setContentDescription("Image description")
                .build()
            ).build()
        ).build()

Java

private LayoutElement myImage() {
   return new Image.Builder()
           .setWidth(dp(24f))
           .setHeight(dp(24f))
           .setResourceId("image_id")
           .setModifiers(new Modifiers.Builder()
                   .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build())
                   .setPadding(new Padding.Builder().setStart(dp(12f)).build())
                   .setSemantics(new Semantics.Builder()
                           .setContentDescription("Image description")
                           .build()
                   ).build()
           ).build();
}

Spannable

Spannable là loại vùng chứa đặc biệt có nhiệm vụ sắp xếp các phần tử tương tự như văn bản. Vùng chứa này hữu ích khi bạn muốn áp dụng kiểu khác cho duy nhất một chuỗi con trong khối văn bản lớn hơn – đây là điều không thể áp dụng với phần tử Text.

Vùng chứa Spannable chứa phần tử con Span. Bạn không được phép dùng các phần tử con khác hoặc các thực thể Spannable lồng nhau.

Có hai loại phần tử con Span:

  • SpanText: hiển thị văn bản có một kiểu cụ thể.
  • SpanImage: hiển thị hình ảnh cùng dòng với văn bản.

Ví dụ: bạn có thể in nghiêng từ "world" (mọi người) trong thẻ thông tin "Hello world" (Chào mọi người) và chèn một hình ảnh giữa các từ, như trong mã mẫu sau đây:

Kotlin

private fun mySpannable(): LayoutElement =
    Spannable.Builder()
        .addSpan(SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(SpanText.Builder()
            .setText("world")
            .setFontStyle(FontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build()

Java

private LayoutElement mySpannable() {
   return new Spannable.Builder()
        .addSpan(new SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(new SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(new SpanText.Builder()
            .setText("world")
            .setFontStyle(newFontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build();
}

Làm việc với các tài nguyên

Ô không có quyền truy cập vào bất kỳ tài nguyên nào trong ứng dụng của bạn. Điều này có nghĩa là bạn không thể chuyển mã nhận dạng hình ảnh Android vào phần tử bố cục Image và kỳ vọng nó sẽ thực hiện phân giải. Thay vào đó, hãy ghi đè phương thức onTileResourcesRequest() và cung cấp mọi tài nguyên theo cách thủ công.

Có 2 cách để cung cấp hình ảnh trong phương thức onTileResourcesRequest():

Kotlin

override fun onTileResourcesRequest(
    requestParams: ResourcesRequest
) = Futures.immediateFuture(
Resources.Builder()
    .setVersion("1")
    .addIdToImageMapping("image_from_resource", ImageResource.Builder()
        .setAndroidResourceByResId(AndroidImageResourceByResId.Builder()
            .setResourceId(R.drawable.image_id)
            .build()
        ).build()
    )
    .addIdToImageMapping("image_inline", ImageResource.Builder()
        .setInlineResource(InlineImageResource.Builder()
            .setData(imageAsByteArray)
            .setWidthPx(48)
            .setHeightPx(48)
            .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
            .build()
        ).build()
    ).build()
)

Java

@Override
protected ListenableFuture<Resources> onTileResourcesRequest(
       @NonNull ResourcesRequest requestParams
) {
return Futures.immediateFuture(
    new Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping("image_from_resource", new ImageResource.Builder()
            .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder()
                .setResourceId(R.drawable.image_id)
                .build()
            ).build()
        )
        .addIdToImageMapping("image_inline", new ImageResource.Builder()
            .setInlineResource(new InlineImageResource.Builder()
                .setData(imageAsByteArray)
                .setWidthPx(48)
                .setHeightPx(48)
                .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                .build()
            ).build()
        ).build()
);
}

Danh sách kiểm tra hình ảnh xem trước ô

Hệ thống hiển thị hình ảnh xem trước thẻ thông tin được tham chiếu trong tệp kê khai ứng dụng Android trong trình chỉnh sửa băng chuyền thẻ thông tin. Trình chỉnh sửa này xuất hiện trên cả thiết bị Wear OS và trong ứng dụng đồng hành với đồng hồ trên điện thoại.

Để giúp người dùng khai thác tối đa hình ảnh xem trước này, hãy xác minh các thông tin chi tiết sau đây về thẻ thông tin:

  • Phản ánh thiết kế mới nhất. Bản xem trước phải thể hiện chính xác thiết kế mới nhất của thẻ thông tin.
  • Sử dụng giao diện màu tĩnh. Sử dụng giao diện màu tĩnh của thẻ thông tin, chứ không phải giao diện màu động.
  • Có biểu tượng ứng dụng. Kiểm tra để đảm bảo biểu tượng ứng dụng của bạn xuất hiện ở đầu hình ảnh xem trước.
  • Hiển thị trạng thái đã tải/đã đăng nhập. Bản xem trước phải hiển thị trạng thái "đã tải" hoặc "đã đăng nhập" có đầy đủ chức năng, tránh mọi nội dung trống hoặc phần giữ chỗ.
  • Tận dụng các quy tắc phân giải tài nguyên để tuỳ chỉnh (không bắt buộc). Hãy cân nhắc sử dụng quy tắc phân giải tài nguyên của Android để cung cấp bản xem trước phù hợp với chế độ cài đặt kích thước màn hình, ngôn ngữ hoặc ngôn ngữ của thiết bị. Điều này đặc biệt hữu ích nếu giao diện của thẻ thông tin thay đổi trên các thiết bị.