Tương tác với thẻ thông tin

Thẻ thông tin không chỉ hiển thị thông tin mà còn có thể tương tác. Để tạo một phần tử như textButton() phản hồi các thao tác nhấn, hãy tạo một trình xử lý lượt nhấp bằng clickable() và liên kết trình xử lý đó với phần tử bố cục.

Bạn có thể định cấu hình Clickable để kích hoạt một hành động theo hai cách chính:

  1. Khởi chạy hoạt động trực tiếp: Sử dụng launchAction() trong trường hợp bạn cần mở một hoạt động ngay lập tức.
  2. Uỷ quyền cho dịch vụ thẻ thông tin: Sử dụng loadAction() để kích hoạt logic trong TileService. Đây là một phương pháp linh hoạt hơn cho phép bạn làm mới nội dung của thẻ thông tin, cập nhật trạng thái của thẻ thông tin hoặc khởi chạy một hoạt động phức tạp hơn.

Chạy một hoạt động đã xuất

Nếu một thao tác nhấn của người dùng sẽ ngay lập tức khởi chạy một hoạt động, hãy sử dụng launchAction(). Cung cấp ComponentName để xác định hoạt động. Bạn phải xuất hoạt động. Với phương pháp này, bạn có thể truyền các phần bổ sung Intent bằng thao tác. Tuy nhiên, bạn không thể đặt cờ Intent tuỳ chỉnh.

Ví dụ sau đây cho biết cách tạo Clickable để chạy TileActivity với hai phần bổ sung là nameage:

textButton(
    labelContent = {
        text("launchAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        launchAction(
            ComponentName(
                "com.example.wear",
                "com.example.wear.snippets.m3.tile.TileActivity",
            ),
            mapOf(
                "name" to ActionBuilders.stringExtra("Bartholomew"),
                "age" to ActionBuilders.intExtra(21),
            ),
        )
    ),
)

Bên trong hoạt động đã chạy, hãy truy xuất các giá trị từ các phần bổ sung của ý định:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // When this activity is launched from the tile InteractionLaunchAction,
    // "name" will be "Bartholomew" and "age" will be 21
    val name = intent.getStringExtra("name")
    val age = intent.getStringExtra("age")

    // ...
}

Xử lý các lượt tương tác trong dịch vụ thẻ thông tin

Để tương tác linh hoạt hơn, hãy sử dụng loadAction(). Khi người dùng nhấn vào một phần tử được định cấu hình bằng loadAction, hệ thống sẽ gọi lại TileService.onTileRequest(). Điều này cho phép bạn chạy logic trong dịch vụ của mình để cập nhật thẻ thông tin, thay đổi trạng thái của thẻ thông tin và thực hiện các tác vụ phức tạp hơn.

Làm mới nội dung của thẻ thông tin

Cách sử dụng loadAction đơn giản nhất là báo hiệu làm mới. Gọi loadAction mà không có đối số. Khi được nhấn vào, hệ thống sẽ gọi onTileRequest(), cho phép dịch vụ của bạn trả về một bố cục mới có nội dung đã cập nhật.

textButton(
    onClick = clickable(loadAction()),
    labelContent = { text("Refresh".layoutString) },
)

Phân biệt giữa nhiều thành phần tương tác

Nếu thẻ thông tin của bạn chứa nhiều phần tử tương tác, bạn có thể liên kết một mã nhận dạng với đối tượng sửa đổi Clickable:

Bên trong onTileRequest(), bạn có thể kiểm tra mã nhận dạng này bằng cách sử dụng requestParams.currentState.lastClickableId để quyết định hành động cần thực hiện.

Ví dụ: Chạy một hoạt động bằng đường liên kết sâu

Mẫu này rất phù hợp để khởi chạy một hoạt động bằng đường liên kết sâu. Thao tác nhấn của người dùng sẽ tải lại thẻ thông tin, dịch vụ của bạn sẽ kiểm tra mã nhận dạng, sau đó khởi chạy hoạt động mới. Để kiểm soát ngăn xếp lui, hãy sử dụng TaskStackBuilder để mang lại trải nghiệm điều hướng tốt hơn cho người dùng. Khi người dùng nhấn vào phần tử này, họ sẽ được chuyển thẳng đến màn hình được liên kết sâu (màn hình message_detail/1 trong ví dụ). Vì đã sử dụng .addNextIntentWithParentStack(), nên hoạt động mẹ cũng được thêm vào ngăn xếp lui. Điều này có nghĩa là nếu người dùng vuốt ngược, họ sẽ chuyển đến màn hình chính của ứng dụng (MessageList trong ví dụ) thay vì thoát ngay đến thẻ thông tin. Thao tác vuốt ngược lần thứ hai sẽ đưa các thẻ thông tin đó trở lại thẻ thông tin.

Sau đó, trong TileActivity, hãy định cấu hình điều hướng để khớp với mẫu googleandroidsnippets://app/message_detail/{id}.

Sử dụng TaskStackBuilder để mang lại trải nghiệm điều hướng tốt hơn cho người dùng. Khi người dùng nhấn vào phần tử này, họ sẽ được chuyển thẳng đến màn hình được liên kết sâu – trong ví dụ này, đó là màn hình message_detail/1. Vì đã sử dụng .addNextIntentWithParentStack(), nên hoạt động mẹ cũng được thêm vào ngăn xếp lui. Điều này có nghĩa là nếu người dùng vuốt ngược, họ sẽ chuyển đến màn hình chính của ứng dụng (MessageList trong ví dụ) thay vì thoát ngay đến thẻ thông tin. Khi vuốt ngược lại lần thứ hai, các thẻ thông tin sẽ quay lại thẻ thông tin.

Cập nhật trạng thái trong thẻ thông tin

Thẻ thông tin của bạn có một đối tượng StateBuilders.State lưu trữ các cặp khoá-giá trị và tồn tại trong các lần tải lại. Bạn có thể sử dụng loadAction() để cập nhật trạng thái này khi người dùng tương tác với thẻ thông tin.

Để thực hiện việc này, hãy truyền DynamicDataMap vào loadAction() chứa các giá trị trạng thái mới.

textButton(
    labelContent = {
        text("loadAction()".layoutString, typography = BODY_LARGE)
    },
    onClick =
    clickable(
        action =
        loadAction(
            dynamicDataMapOf(
                stringAppDataKey("name") mapTo "Javier",
                intAppDataKey("age") mapTo 37,
            )
        )
    ),
)

Khi thao tác này kích hoạt onTileRequest(), bạn có thể đọc dữ liệu đã cập nhật từ requestParams.currentState.stateMap. Điều này rất hữu ích cho các hoạt động tương tác trực tiếp sửa đổi dữ liệu trên thẻ thông tin, chẳng hạn như tăng bộ đếm hoặc bật/tắt chế độ cài đặt.

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile> {

    // When triggered by loadAction(), "name" will be "Javier", and "age" will
    // be 37.
    with(requestParams.currentState.stateMap) {
        val name = this[stringAppDataKey("name")]
        val age = this[intAppDataKey("age")]
    }

    // ...
}