Tạo thẻ thông tin đầu tiên trong Wear OS

1. Giới thiệu

đồng hồ ảnh động, người dùng vuốt mặt đồng hồ sang thẻ thông tin đầu tiên là thông tin dự báo, sau đó đến thẻ thông tin hẹn giờ rồi quay lại

Thẻ thông tin Wear OS giúp bạn dễ dàng truy cập thông tin và các hành động mà người dùng cần để hoàn thành công việc. Chỉ cần thao tác vuốt từ mặt đồng hồ, người dùng có thể thấy thông tin dự báo mới nhất hoặc khởi động đồng hồ hẹn giờ.

Thẻ thông tin chạy dưới dạng một phần giao diện người dùng hệ thống thay vì chạy trong vùng chứa ứng dụng. Chúng ta sẽ sử dụng Dịch vụ để mô tả bố cục và nội dung của thẻ thông tin. Sau đó, giao diện người dùng hệ thống sẽ hiển thị thẻ thông tin khi cần.

Bạn sẽ thực hiện

35a459b77a2c9d52.png

Bạn sẽ tạo thẻ thông tin cho một ứng dụng nhắn tin để cho thấy các cuộc trò chuyện gần đây. Từ giao diện này, người dùng có thể chuyển sang 3 tác vụ phổ biến sau:

  • Mở một cuộc trò chuyện
  • Tìm kiếm một cuộc trò chuyện
  • Soạn một tin nhắn mới

Kiến thức bạn sẽ học được

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách viết Thẻ thông tin dành cho Wear OS của riêng mình, bao gồm cách:

  • Tạo một TileService
  • Thử nghiệm thẻ thông tin trên thiết bị
  • Xem trước giao diện người dùng của thẻ thông tin trong Android Studio
  • Phát triển giao diện người dùng của thẻ thông tin
  • Thêm hình ảnh
  • Xử lý các lượt tương tác

Điều kiện tiên quyết

  • Hiểu biết cơ bản về Kotlin

2. Chuẩn bị

Ở bước này, bạn sẽ thiết lập môi trường và tải dự án ban đầu xuống.

Bạn cần có

Trước khi bắt đầu, nếu bạn chưa quen dùng Wear OS, hãy đọc hướng dẫn nhanh hữu ích này. Hướng dẫn trên bao gồm hướng dẫn thiết lập trình mô phỏng Wear OS và mô tả cách sử dụng hệ thống.

Tải mã xuống

Nếu đã cài đặt git, bạn chỉ cần chạy lệnh dưới đây để nhân bản mã từ kho lưu trữ này.

git clone https://github.com/android/codelab-wear-tiles.git
cd codelab-wear-tiles

Nếu không có git, bạn có thể nhấp vào nút sau đây để tải tất cả mã dành cho lớp học lập trình này:

Mở dự án trong Android Studio

Trên cửa sổ "Welcome to Android Studio" (Chào mừng bạn đến với Android Studio), hãy chọn c01826594f360d94.png Open an Existing Project (Mở một Dự án hiện có) hoặc File > Open (Tệp > Mở) rồi chọn thư mục [Download Location].

3. Tạo thẻ thông tin cơ bản

Điểm truy cập của một thẻ thông tin là dịch vụ thẻ thông tin. Ở bước này, bạn sẽ đăng ký dịch vụ và xác định bố cục cho thẻ thông tin.

HelloWorldTileService

Một lớp triển khai TileService cần chỉ định 2 phương thức sau:

  • onTileResourcesRequest(requestParams: ResourcesRequest): ListenableFuture<Resources>
  • onTileRequest(requestParams: TileRequest): ListenableFuture<Tile>

Phương thức đầu tiên trả về một đối tượng Resources giúp liên kết các chuỗi mã nhận dạng với những tài nguyên hình ảnh mà chúng ta sẽ dùng trong thẻ thông tin.

Phương thức thứ hai trả về nội dung mô tả thẻ thông tin bao gồm cả bố cục. Đây là nơi chúng ta xác định bố cục thẻ thông tin và cách dữ liệu liên kết với bố cục này.

Mở HelloWorldTileService.kt từ mô-đun start. Tất cả thay đổi mà bạn thực hiện sẽ có mặt ở mô-đun trên. Ngoài ra, chúng tôi còn cung cấp mô-đun finished nếu bạn muốn xem kết quả của lớp học lập trình.

HelloWorldTileService mở rộng SuspendingTileService, một trình bao bọc phù hợp với coroutine Kotlin trong thư viện Thẻ thông tin Horologist. Horologist là một nhóm thư viện của Google dùng để bổ sung các tính năng mà nhà phát triển Wear OS thường yêu cầu nhưng vẫn chưa có trên Jetpack.

SuspendingTileService cung cấp 2 hàm tạm ngưng (là các phiên bản coroutine tương đương của những hàm trong TileService):

  • suspend resourcesRequest(requestParams: ResourcesRequest): Resources
  • suspend tileRequest(requestParams: TileRequest): Tile

Để tìm hiểu thêm về coroutine, hãy xem tài liệu về Coroutine Kotlin trên Android.

HelloWorldTileService vẫn chưa hoàn tất. Chúng tôi cần đăng ký dịch vụ trong tệp kê khai và cũng cần triển khai tileLayout.

Đăng ký dịch vụ thẻ thông tin

Sau khi được đăng ký trong tệp kê khai, dịch vụ thẻ thông tin sẽ xuất hiện trong danh sách các thẻ thông tin hiện có để người dùng thêm.

Hãy thêm <service> bên trong phần tử <application>:

start/src/main/AndroidManifest.xml

<service
    android:name="com.example.wear.tiles.hello.HelloWorldTileService"
    android:icon="@drawable/ic_waving_hand_24"
    android:label="@string/hello_tile_label"
    android:description="@string/hello_tile_description"
    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>

    <!-- The tile preview shown when configuring tiles on your phone -->
    <meta-data
        android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_hello" />
</service>

Biểu tượng và nhãn được dùng (dưới dạng phần giữ chỗ) khi thẻ thông tin tải lần đầu, hoặc nếu xảy ra lỗi khi tải thẻ thông tin. Tiếp đó, siêu dữ liệu ở phía cuối xác định hình ảnh xem trước, được hiển thị trong băng chuyền khi người dùng thêm một thẻ thông tin.

Xác định bố cục cho thẻ thông tin

HelloWorldTileService có một hàm tên là tileLayout, chứa TODO() là phần nội dung. Hãy thay hàm này bằng phương thức triển khai, nơi chúng ta xác định bố cục cho thẻ thông tin và liên kết dữ liệu:

start/src/main/java/com/example/wear/tiles/hello/HelloWorldTileService.kt

private fun tileLayout(): LayoutElement {
    val text = getString(R.string.hello_tile_body)
    return LayoutElementBuilders.Box.Builder()
        .setVerticalAlignment(LayoutElementBuilders.VERTICAL_ALIGN_CENTER)
        .setWidth(DimensionBuilders.expand())
        .setHeight(DimensionBuilders.expand())
        .addContent(
            LayoutElementBuilders.Text.Builder()
                .setText(text)
                .build()
        )
        .build()
}

Chúng ta sẽ tạo một phần tử Text và thiết lập phần tử này bên trong Box để có thể tiến hành một số thao tác căn chỉnh cơ bản.

Và đó là Thẻ thông tin Wear OS đầu tiên bạn tạo ra! Hãy cài đặt và xem giao diện của thẻ thông tin này.

4. Kiểm thử thẻ thông tin trên một thiết bị

Sau khi chọn mô-đun khởi đầu trong trình đơn thả xuống cấu hình chạy, bạn có thể cài đặt ứng dụng (mô-đun start) trên thiết bị hoặc trình mô phỏng và cài đặt thẻ thông tin theo cách thủ công như cách người dùng thao tác.

Tuy nhiên, đối với mục đích phát triển, hãy sử dụng Direct Surface Launch, một tính năng ra mắt cùng với Android Studio Dolphin, để tạo cấu hình chạy mới nhằm khởi chạy thẻ thông tin ngay trên Android Studio. Chọn "Edit Configurations…" (Chỉnh sửa cấu hình…) trong trình đơn thả xuống ở bảng trên cùng.

Trình đơn thả xuống để chạy cấu hình ở bảng trên cùng trong Android Studio. Trình đơn Chỉnh sửa cấu hình được đánh dấu.

Nhấp vào nút "Thêm cấu hình mới" rồi chọn "Thẻ thông tin trong Wear OS". Thêm tên mô tả, sau đó chọn mô-đun Tiles_Code_Lab.start và thẻ thông tin HelloWorldTileService.

Nhấn "OK" để hoàn tất.

Trình đơn Chỉnh sửa cấu hình chứa Thẻ thông tin Wear OS có tên HelloTile đang được định cấu hình.

Direct Surface Launch cho phép chúng ta nhanh chóng kiểm tra thẻ thông tin trên trình mô phỏng hoặc thiết bị Wear OS thực tế. Hãy dùng thử bằng cách chạy "HelloTile". Giao diện sẽ giống như ảnh chụp màn hình dưới đây.

Đồng hồ tròn hiện "Time to create a tile!" (Đã đến lúc tạo thẻ thông tin!) bằng chữ trắng trên nền đen

5. Tạo một thẻ thông tin cho ứng dụng nhắn tin

Đồng hồ tròn cho thấy 5 nút tròn được sắp xếp theo hình kim tự tháp 2x3. Nút đầu tiên và thứ 3 cho thấy tên viết tắt bằng chữ màu tím, nút thứ 2 và thứ 4 cho thấy ảnh hồ sơ, còn nút cuối cùng là biểu tượng tìm kiếm. Bên dưới các nút là một khối nhỏ gọn màu tím có nội dung "New" (Mới) với văn bản màu đen.

Thẻ thông tin cho ứng dụng nhắn tin chúng ta sắp tạo có tính đặc trưng của một thẻ thông tin thực tế. Không giống như ví dụ về HelloWorld, ví dụ này tải dữ liệu từ kho lưu trữ cục bộ, tìm nạp hình ảnh từ mạng để hiển thị và xử lý hoạt động tương tác để mở ứng dụng ngay trong thẻ thông tin.

MessagingTileService

MessagingTileService mở rộng lớp SuspendingTileService mà chúng ta đã thấy trước đó.

Điểm khác biệt chính giữa ví dụ này và ví dụ trước là hiện tại chúng ta đang theo dõi dữ liệu từ kho lưu trữ, đồng thời tìm nạp dữ liệu hình ảnh từ trên mạng.

MessagingTileRenderer

MessagingTileRenderer mở rộng lớp SingleTileLayoutRenderer (một lớp trừu tượng khác trong Thẻ thông tin Horologist). Lớp này hoàn toàn đồng bộ: trạng thái được truyền vào các hàm kết xuất, giúp bạn dễ dàng sử dụng hơn trong các lần kiểm thử và xem trước trên Android Studio.

Ở bước tiếp theo, chúng ta sẽ xem cách thêm bản xem trước trên Android Studio cho thẻ thông tin.

6. Thêm hàm xem trước

Chúng ta có thể sử dụng các hàm xem trước Thẻ thông tin đã phát hành trong phiên bản 1.4 của thư viện Thẻ thông tin Jetpack (hiện có phiên bản alpha) để xem trước giao diện người dùng thẻ thông tin trong Android Studio. Việc này giúp rút ngắn vòng hồi tiếp khi phát triển giao diện người dùng, từ đó tăng tốc độ phát triển.

Hãy thêm một bản xem trước thẻ thông tin cho MessagingTileRenderer ở cuối tệp.

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

@Preview(device = WearDevices.SMALL_ROUND)
@Preview(device = WearDevices.LARGE_ROUND)
fun messagingTileLayoutPreview(context: Context): TilePreviewData {
    return TilePreviewData { request ->
        MessagingTileRenderer(context).renderTimeline(
            MessagingTileState(knownContacts),
            request
        )
    }
}

Lưu ý không cung cấp chú giải @Composable. Mặc dù Thẻ thông tin và Hàm có khả năng kết hợp dùng cùng một giao diện người dùng xem trước, nhưng Thẻ thông tin không sử dụng Compose và không phải là thành phần kết hợp.

Hãy sử dụng chế độ chỉnh sửa "Split" (Chia đôi) để xem trước thẻ thông tin:

khung hiển thị chia đôi màn hình của Android Studio với mã xem trước ở bên trái và hình ảnh thẻ thông tin ở bên phải.

Ở bước tiếp theo, chúng ta sẽ dùng Tiles Material để cập nhật bố cục.

7. Thêm Tiles Material

Tiles Material cung cấp các bố cụcthành phần Material tạo sẵn, giúp bạn tạo ra những thẻ thông tin phù hợp với Material Design mới nhất cho Wear OS.

Thêm phần phụ thuộc Tiles Material vào tệp build.gradle:

start/build.gradle

implementation "androidx.wear.protolayout:protolayout-material:$protoLayoutVersion"

Thêm mã cho nút vào cuối tệp kết xuất cũng như bản xem trước:

start/src/main/java/MessagingTileRenderer.kt

private fun searchLayout(
    context: Context,
    clickable: ModifiersBuilders.Clickable,
) = Button.Builder(context, clickable)
    .setContentDescription(context.getString(R.string.tile_messaging_search))
    .setIconContent(MessagingTileRenderer.ID_IC_SEARCH)
    .setButtonColors(ButtonColors.secondaryButtonColors(MessagingTileTheme.colors))
    .build()

Chúng ta cũng có thể làm tương tự để tạo bố cục cho danh bạ:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun contactLayout(
    context: Context,
    contact: Contact,
    clickable: ModifiersBuilders.Clickable,
) = Button.Builder(context, clickable)
    .setContentDescription(contact.name)
    .apply {
        if (contact.avatarUrl != null) {
            setImageContent(contact.imageResourceId())
        } else {
            setTextContent(contact.initials)
            setButtonColors(ButtonColors.secondaryButtonColors(MessagingTileTheme.colors))
        }
    }
    .build()

Tiles Material không chỉ bao gồm các thành phần. Thay vì sử dụng một loạt các cột và hàng lồng nhau, chúng ta có thể dùng bố cục trong Tiles Material để nhanh chóng tạo được giao diện mong muốn.

Ở đây, chúng ta có thể sử dụng PrimaryLayoutMultiButtonLayout để sắp xếp 4 địa chỉ liên hệ và nút tìm kiếm. Cập nhật hàm messagingTileLayout() trong MessagingTileRenderer với các bố cục sau:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun messagingTileLayout(
    context: Context,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    state: MessagingTileState
) = PrimaryLayout.Builder(deviceParameters)
    .setResponsiveContentInsetEnabled(true)
    .setContent(
        MultiButtonLayout.Builder()
            .apply {
                // In a PrimaryLayout with a compact chip at the bottom, we can fit 5 buttons.
                // We're only taking the first 4 contacts so that we can fit a Search button too.
                state.contacts.take(4).forEach { contact ->
                    addButtonContent(
                        contactLayout(
                            context = context,
                            contact = contact,
                            clickable = emptyClickable
                        )
                    )
                }
            }
            .addButtonContent(searchLayout(context, emptyClickable))
            .build()
    )
    .build()

96fee80361af2c0f.png

MultiButtonLayout hỗ trợ tối đa 7 nút và bố trí các nút với khoảng cách phù hợp.

Hãy thêm một CompactChip "New" (Mới) làm khối "primary" (chính) của PrimaryLayout trong hàm messagingTileLayout():

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

.setPrimaryChipContent(
        CompactChip.Builder(
            /* context = */ context,
            /* text = */ context.getString(R.string.tile_messaging_create_new),
            /* clickable = */ emptyClickable,
            /* deviceParameters = */ deviceParameters
        )
            .setChipColors(ChipColors.primaryChipColors(MessagingTileTheme.colors))
            .build()
    )

2041bdca8a46458b.png

Ở bước tiếp theo, chúng ta sẽ thêm những hình ảnh còn thiếu.

8. Thêm hình ảnh

Nhìn chung, Thẻ thông tin bao gồm 2 thành phần: phần tử bố cục (tham chiếu tài nguyên theo chuỗi mã nhận dạng) và chính tài nguyên đó (có thể là hình ảnh).

Cung cấp hình ảnh cục bộ là một tác vụ đơn giản: mặc dù không thể trực tiếp dùng tài nguyên có thể vẽ trên Android nhưng bạn có thể dùng hàm tiện lợi do Horologist cung cấp để dễ dàng chuyển đổi các tài nguyên đó sang định dạng được yêu cầu. Sau đó, hãy dùng hàm addIdToImageMapping để liên kết hình ảnh với mã nhận dạng tài nguyên. Ví dụ:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

addIdToImageMapping(
    ID_IC_SEARCH,
    drawableResToImageResource(R.drawable.ic_search_24)
)

Đối với hình ảnh từ xa, hãy dùng Coil, một trình tải hình ảnh dựa trên coroutine của Kotlin, để tải qua mạng.

Mã sau đây được viết sẵn để thực hiện việc này:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileService.kt

override suspend fun resourcesRequest(requestParams: ResourcesRequest): Resources {
    val avatars = imageLoader.fetchAvatarsFromNetwork(
        context = this@MessagingTileService,
        requestParams = requestParams,
        tileState = latestTileState()
    )
    return renderer.produceRequestedResources(avatars, requestParams)
}

Vì trình kết xuất thẻ thông tin hoàn toàn đồng bộ nên dịch vụ thẻ thông tin sẽ tìm nạp bitmap từ trên mạng. Như trước đây, tuỳ vào kích thước mà có thể bạn nên dùng WorkManager để tìm nạp trước hình ảnh, nhưng đối với lớp học lập trình này, chúng ta sẽ trực tiếp tìm nạp các hình ảnh đó.

Chúng ta truyền bản đồ avatars (Contact đến Bitmap) đến trình kết xuất dưới dạng "trạng thái" cho các tài nguyên. Giờ đây, trình kết xuất có thể chuyển đổi các bitmap này thành tài nguyên hình ảnh cho thẻ thông tin.

Mã này cũng đã được viết:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

override fun ResourceBuilders.Resources.Builder.produceRequestedResources(
    resourceState: Map<Contact, Bitmap>,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    resourceIds: List<String>
) {
    addIdToImageMapping(
        ID_IC_SEARCH,
        drawableResToImageResource(R.drawable.ic_search_24)
    )

    resourceState.forEach { (contact, bitmap) ->
        addIdToImageMapping(
            /* id = */ contact.imageResourceId(),
            /* image = */ bitmap.toImageResource()
        )
    }
}

Vì vậy, nếu dịch vụ đang tìm nạp bitmap và trình kết xuất đang chuyển đổi bitmap này thành tài nguyên hình ảnh, tại sao thẻ thông tin lại không hiển thị hình ảnh?

Có chứ! Nếu chạy thẻ thông tin trên một thiết bị (có quyền truy cập Internet), bạn sẽ thấy các hình ảnh thực sự tải. Vấn đề chỉ nằm ở bản xem trước, vì chúng ta chưa truyền tài nguyên nào đến TilePreviewData().

Đối với thẻ thông tin thật, chúng ta sẽ tìm nạp bitmap từ trên mạng và ánh xạ bitmap này đến các địa chỉ liên hệ, nhưng chúng ta không cần dùng mạng đối với bản xem trước và các lần kiểm thử.

Chúng ta cần thực hiện 2 thay đổi. Thứ nhất, hãy tạo một hàm previewResources() để trả về đối tượng Resources:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun previewResources() = Resources.Builder()
    .addIdToImageMapping(ID_IC_SEARCH, drawableResToImageResource(R.drawable.ic_search_24))
    .addIdToImageMapping(knownContacts[1].imageResourceId(), drawableResToImageResource(R.drawable.ali))
    .addIdToImageMapping(knownContacts[2].imageResourceId(), drawableResToImageResource(R.drawable.taylor))
    .build()

Thứ hai, hãy cập nhật messagingTileLayoutPreview() để truyền vào tài nguyên:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

@Preview(device = WearDevices.SMALL_ROUND)
@Preview(device = WearDevices.LARGE_ROUND)
fun messagingTileLayoutPreview(context: Context): TilePreviewData {
    return TilePreviewData({ previewResources() }) { request ->
        MessagingTileRenderer(context).renderTimeline(
            MessagingTileState(knownContacts),
            request
        )
    }
}

Bây giờ, nếu chúng ta làm mới bản xem trước, những hình ảnh đó sẽ hiển thị:

3142b42717407059.png

Ở bước tiếp theo, chúng ta sẽ xử lý các lượt nhấp vào từng phần tử.

9. Xử lý các lượt tương tác

Một trong những điều hữu ích nhất mà thẻ thông tin mang lại là cung cấp lối tắt đến hành trình trọng yếu của người dùng. Khác với trình chạy ứng dụng chỉ mở ứng dụng, ở đây chúng ta có không gian để cung cấp các lối tắt theo ngữ cảnh vào một màn hình cụ thể trong ứng dụng.

Cho đến nay, chúng ta đã sử dụng emptyClickable cho chip (khối) và mỗi nút. Bạn có thể làm điều này cho các bản xem trước không có tính tương tác, nhưng hãy tìm hiểu cách thêm thao tác cho các thành phần.

Hai trình tạo từ lớp 'ActionBuilders' xác định các hành động có thể nhấp là LoadActionLaunchAction.

LoadAction

Bạn có thể sử dụng LoadAction nếu muốn thực hiện logic trong dịch vụ thẻ thông tin khi người dùng nhấp vào một phần tử, ví dụ: tăng một bộ đếm.

.setClickable(
    Clickable.Builder()
        .setId(ID_CLICK_INCREMENT_COUNTER)
        .setOnClick(ActionBuilders.LoadAction.Builder().build())
        .build()
    )
)

Khi người dùng nhấp vào nút này, onTileRequest sẽ được gọi trong dịch vụ (tileRequest trong SuspendingTileService). Vì vậy, đây là cơ hội tốt để làm mới giao diện người dùng thẻ thông tin:

override suspend fun tileRequest(requestParams: TileRequest): Tile {
    if (requestParams.state.lastClickableId == ID_CLICK_INCREMENT_COUNTER) {
        // increment counter
    }
    // return an updated tile
}

LaunchAction

Bạn có thể dùng LaunchAction để chạy một hoạt động. Trong MessagingTileRenderer, hãy cập nhật khả năng nhấp cho nút tìm kiếm.

Nút tìm kiếm được xác định bằng hàm searchLayout() trong MessagingTileRenderer. Hàm này đã lấy Clickable làm tham số. Tuy nhiên, tính đến thời điểm hiện tại, chúng ta đã truyền emptyClickable. Đây là phương thức triển khai không hoạt động, không thực hiện bất kỳ hành động nào khi người dùng nhấp vào nút trên.

Hãy cập nhật messagingTileLayout() để truyền hành động nhấp thật.

  1. Thêm một tham số mới searchButtonClickable (thuộc loại ModifiersBuilders.Clickable).
  2. Truyền tham số này vào hàm searchLayout() hiện có.

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun messagingTileLayout(
    context: Context,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    state: MessagingTileState,
    searchButtonClickable: ModifiersBuilders.Clickable
...
    .addButtonContent(searchLayout(context, searchButtonClickable))

Chúng ta cũng cần cập nhật renderTile, đây chính là nơi gọi messagingTileLayout do vừa thêm một tham số mới (searchButtonClickable). Sau đó, chúng ta sẽ sử dụng hàm launchActivityClickable() để tạo một hàm mới có thể nhấp và truyền openSearch() ActionBuilder dưới dạng thao tác:

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

override fun renderTile(
    state: MessagingTileState,
    deviceParameters: DeviceParametersBuilders.DeviceParameters
): LayoutElementBuilders.LayoutElement {
    return messagingTileLayout(
        context = context,
        deviceParameters = deviceParameters,
        state = state,
        searchButtonClickable = launchActivityClickable("search_button", openSearch())
    )
}

Mở launchActivityClickable để xem cách hoạt động (đã được xác định) của hàm:

start/src/main/java/com/example/wear/tiles/messaging/tile/ClickableActions.kt

internal fun launchActivityClickable(
    clickableId: String,
    androidActivity: ActionBuilders.AndroidActivity
) = ModifiersBuilders.Clickable.Builder()
    .setId(clickableId)
    .setOnClick(
        ActionBuilders.LaunchAction.Builder()
            .setAndroidActivity(androidActivity)
            .build()
    )
    .build()

Cách hoạt động rất giống với LoadAction – điểm khác biệt chính là chúng ta gọi setAndroidActivity. Trong cùng một tệp, chúng ta có nhiều ví dụ về ActionBuilder.AndroidActivity.

Đối với openSearch được dùng cho khả năng nhấp này, ta gọi setMessagingActivity và truyền thêm một chuỗi để xác định đây là lượt nhấp vào nút nào.

start/src/main/java/com/example/wear/tiles/messaging/tile/ClickableActions.kt

internal fun openSearch() = ActionBuilders.AndroidActivity.Builder()
    .setMessagingActivity()
    .addKeyToExtraMapping(
        MainActivity.EXTRA_JOURNEY,
        ActionBuilders.stringExtra(MainActivity.EXTRA_JOURNEY_SEARCH)
    )
    .build()

...

internal fun ActionBuilders.AndroidActivity.Builder.setMessagingActivity(): ActionBuilders.AndroidActivity.Builder {
    return setPackageName("com.example.wear.tiles")
        .setClassName("com.example.wear.tiles.messaging.MainActivity")
}

Chạy thẻ thông tin (nhớ chạy thẻ thông tin "messaging" (nhắn tin) chứ không phải thẻ thông tin "hello" (xin chào)) rồi nhấp vào nút tìm kiếm. Thao tác này sẽ mở MainActivity và hiển thị văn bản để xác nhận có lượt nhấp vào nút tìm kiếm.

Cách thêm thao tác cho các nút khác cũng tương tự như vậy. ClickableActions chứa các hàm bạn cần. Nếu bạn cần gợi ý, hãy xem MessagingTileRenderer trong mô-đun finished.

10. Xin chúc mừng

Xin chúc mừng! Bạn đã tìm hiểu cách xây dựng thẻ thông tin dành cho Wear OS!

Tiếp theo là gì?

Để biết thêm thông tin, hãy xem các phương pháp triển khai Thẻ thông tin Golden trên GitHub, hướng dẫn về Thẻ thông tin trong Wear OSnguyên tắc thiết kế.