Bố cục tư thế trên mặt bàn với Lưới và mediaQuery

Biểu tượng điểm xếp hạng 4 sao

Tư thế đặt trên bàn của thiết bị có thể gập lại sẽ chia một màn hình thành hai khu vực hiển thị chức năng được phân chia bằng đường gấp (hoặc bản lề) vật lý. Tư thế đặt trên bàn cho phép bạn đặt nội dung chính của ứng dụng (chẳng hạn như trình phát video hoặc canvas trò chơi) ở nửa trên, đồng thời đặt các phần tử tương tác (chẳng hạn như các nút điều khiển nội dung nghe nhìn hoặc bảng điều khiển) ở nửa dưới.

Thiết bị có thể gập lại ở tư thế đặt trên bàn, cho thấy nội dung video trên màn hình trên cùng và các nút điều khiển phát trên màn hình dưới cùng.
Hình 1. Tư thế đặt trên bàn chia nội dung và các chế độ kiểm soát tương tác trên nếp gập vật lý.

Các phương pháp hay nhất

Để thêm chế độ hỗ trợ trên bàn vào ứng dụng, hãy dùng API Grid để xác định bố cục có 2 hàng và 1 cột, đồng thời áp dụng truy vấn nội dung nghe nhìn về tư thế cửa sổ trên bàn.

  • Phản ứng khi phát hiện tư thế trên mặt bàn: Sử dụng composable mediaQuery để theo dõi state thiết bị. Khi thiết bị được gập lại ở tư thế trên mặt bàn (windowPosture == Posture.Tabletop), hãy chuyển đổi bố cục một cách linh động mà không cần khởi động lại hoạt động hoặc xử lý vòng đời phức tạp.
  • Cấu trúc bố cục bằng Grid: Khi ở tư thế đặt trên bàn, hãy sử dụng API Grid (2 rows, 1 column) để tách riêng nội dung trực quan chính thành hàng trên ở phía trên nếp gấp và các chế độ điều khiển tương tác thành hàng dưới ở phía dưới nếp gấp.
  • Tận dụng chỉ mục z ngầm cho lớp phủ: Ở tư thế tiêu chuẩn (không phải trên mặt bàn), hãy chỉ định nhiều mã nhận dạng vùng cho cùng một ô để phủ các nút điều khiển lên trình phát. Grid tự động kết xuất các mục từ sau ra trước theo thứ tự khai báo.
  • Cung cấp hiệu ứng chuyển đổi mượt mà: Đảm bảo trạng thái và vị trí cuộn được giữ nguyên khi chuyển đổi giữa bố cục toàn màn hình tiêu chuẩn và tư thế đặt trên bàn.

Nguyên liệu

  • Grid: Một vùng chứa bố cục thích ứng cho phép bạn đặt các mục vào các hàng và cột có thể định cấu hình, lý tưởng để chia nội dung trên các vùng màn hình riêng biệt.
  • mediaQuery: Một API Jetpack Compose dùng để truy vấn tư thế cửa sổ, các lớp kích thước và đặc điểm phần cứng hiện tại của ứng dụng ngay trong các thành phần kết hợp.

Các bước

Truy vấn tư thế thiết bị bằng cách sử dụng mediaQuery(). Khi thiết bị ở tư thế trên mặt bàn, hãy sắp xếp nội dung của ứng dụng thành một lưới dọc có 2 hàng và 1 cột, đảm bảo nội dung chính nằm ở trên cùng và các chế độ điều khiển luôn có thể truy cập ở dưới cùng.

1. Xác định cấu hình Lưới cho chế độ trên bàn

Bên trong một hàm có khả năng kết hợp, hãy xác định các mã nhận dạng vùng bố cục bằng cách sử dụng một enum và thiết lập các khối GridConfigurationScope cho tư thế mặc định và tư thế đặt trên bàn.

Trong defaultConfig, cả hai vùng đều được chỉ định cho cùng một ô (row = 1, column = 1). Grid sử dụng chỉ mục z ngầm định, trong đó các thành phần kết hợp được khai báo sau trong bố cục sẽ được kết xuất trên các thành phần kết hợp trước đó, cho phép bộ điều khiển phủ lên trình phát mà không cần thêm vùng chứa lồng nhau (xem phần Lớp phủ phần tử trên giao diện người dùng bằng Lưới để biết thêm thông tin).

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

2. Phát hiện tư thế ngồi trên bàn và áp dụng cấu hình cho Lưới

Sử dụng mediaQuery để chọn cấu hình đang hoạt động dựa trên windowPosture, truyền config đến Grid và liên kết nội dung có thể kết hợp với mã nhận dạng vùng. Việc khai báo VideoPlayerArea.Player trước VideoPlayerArea.Controller đảm bảo rằng khi cả hai chia sẻ một ô trong defaultConfig, các nút điều khiển sẽ hiển thị phía trên trình phát:

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

Kết quả

Bằng cách kết hợp mediaQuery và Grid, ứng dụng của bạn sẽ tự động phát hiện khi thiết bị có thể gập lại được gập một phần thành tư thế mặt bàn và tự động điều chỉnh giao diện người dùng thành 2 vùng hiển thị chức năng được phân chia bằng nếp gập.

Tài nguyên khác