Danh sách lazy trong Lưới

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

Thành phần kết hợp Grid tạo bố cục màn hình hai chiều có cấu trúc. Grid xác định cấu trúc bố cục thích ứng bằng cách sử dụng các dải (hàng và cột) và khoảng trống được xác định rõ ràng làm cấu trúc nền tảng của giao diện người dùng.

Vì Grid là một vùng chứa cấu trúc chứ không phải là vùng chứa tải lười, nên bạn phải xác định rõ ràng mọi phần tử được đặt trong đó mà không cần tái sử dụng các mục khi cuộn. Do đó, việc kết xuất các tập dữ liệu lớn hoặc động ngay trong Grid có thể gây ra tình trạng thắt cổ chai về hiệu suất vì tất cả các mục đều được kết hợp cùng một lúc.

Để hiển thị các tập hợp dữ liệu lớn trong bố cục màn hình có cấu trúc, hãy nhúng các thành phần tải từng phần như LazyColumn hoặc LazyRow vào các ô Grid. Nhưng xin lưu ý: các dải linh hoạt (có thông số kỹ thuật như 1.fr) sẽ truy vấn kích thước nội tại của các phần tử con. Vì SubcomposeLayout không hỗ trợ các lượt đo lường nội tại, nên việc đặt danh sách tải từng phần bên trong một bản nhạc linh hoạt sẽ gây ra sự cố IllegalStateException. Để đặt danh sách tải từng phần một cách an toàn bên trong một dải lưới linh hoạt, bạn phải sử dụng kích thước GridTrackSize.MinMax (chẳng hạn như minmax(0.dp, 1.fr)) để bỏ qua lượt đo lường nội tại.

Bố cục màn hình có một Tiêu đề ở trên cùng, một danh sách các mục có thể cuộn trong khu vực nội dung chính và một Chân trang ở dưới cùng.
Hình 1. Bố cục màn hình có cấu trúc với tiêu đề, chân trang và LazyColumn được nhúng cho nội dung.

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

  • Sử dụng danh sách tải từng phần thay vì vòng lặp tường minh lớn: Để hiển thị các tập dữ liệu lớn hoặc động trong một Grid có cấu trúc, hãy nhúng các thành phần tải từng phần (thường là LazyColumn hoặc LazyRow) vào các ô lưới cụ thể thay vì tạo vòng lặp tường minh lớn trên các mục, vì Grid không tái chế các mục và có giới hạn 1.000 bản nhạc.
  • Sử dụng kích thước bản nhạc MinMax cho danh sách tải từng phần: Vì LazyColumn và LazyRow không hỗ trợ các lượt đo lường nội tại (xem SubcomposeLayout), hãy sử dụng GridTrackSize.MinMax trên các bản nhạc linh hoạt lưu trữ thành phần tải từng phần để bỏ qua các phép đo lường nội tại một cách an toàn.

Nguyên liệu

  • Grid: Bố cục thành phần kết hợp đặt các mục trong cấu trúc lưới hai chiều được định cấu hình bằng các dải hàng và cột rõ ràng.
  • LazyColumn: Danh sách cuộn dọc chỉ kết hợp và tái chế các mục hiện đang hiển thị trên màn hình.
  • GridTrackSize.MinMax: Thuộc tính định cỡ theo dõi xác định các ranh giới linh hoạt (min và max) để lưu trữ các thành phần tải từng phần một cách an toàn mà không gây ra sự cố đo lường thời gian chạy.
  • gridItem: Tiện ích Compose Modifier chỉ định một phần tử trên giao diện người dùng con cho một ô cụ thể hoặc vùng được đặt tên bên trong Grid.

Các bước

Tạo cấu trúc cho bố cục màn hình bằng cách xác định giá trị nhận dạng vùng ngữ nghĩa, định cấu hình các dải lưới có kích thước minmax để tương thích với danh sách tải từng phần và nhúng LazyColumn vào bên trong vùng nội dung lưới.

1. Định cấu hình các dải lưới và vùng được đặt tên

Tạo một lớp enum để đại diện cho các vùng riêng biệt trong bố cục màn hình, và xác định một hàm lambda GridConfigurationScope cho các dải bố cục và vùng được đặt tên. Sử dụng GridTrackSize.MaxContent cho các hàng tiêu đề và chân trang để phù hợp với kích thước nội dung của chúng, đồng thời sử dụng minmax(0.dp, 1.fr) cho bản nhạc nội dung lưu trữ danh sách tải từng phần để phân bổ không gian linh hoạt mà không cần truy vấn các phép đo nội tại không được hỗ trợ:

enum class ScreenArea {
    Header,
    Content,
    Footer
}


val lazyConfig: GridConfigurationScope.() -> Unit = {
    column(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)
    row(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)

    area(ScreenArea.Header, row = 1, column = 1)
    area(ScreenArea.Content, row = 2, column = 1)
    area(ScreenArea.Footer, row = 3, column = 1)
    gap(8.dp)
}

2. Đặt các thành phần tĩnh trong Grid

Trong thành phần kết hợp, hãy truyền lazyConfig vào vùng chứa Grid. Bên trong lambda content, hãy đặt các thành phần tĩnh (Header và Footer) và định vị các thành phần đó bằng Modifier.gridItem() với giá trị nhận dạng vùng tương ứng.

3. Nhúng LazyColumn vào vùng nội dung

Trong ô nội dung, hãy nhúng LazyColumn bằng Modifier.gridItem(ScreenArea.Content). Vì kênh nội dung được định cấu hình bằng minmax(0.dp, 1.fr) trong Bước 1, nên LazyColumn có thể đo lường và tái chế các mục một cách an toàn khi cuộn mà không cần truy vấn các kích thước nội tại không được hỗ trợ:

@Composable
fun GridWithLazyColumn(
    modifier: Modifier = Modifier,
    items: List<String> = emptyList(),
) {
    Grid(
        modifier = modifier.fillMaxSize(),
        config = lazyConfig
    ) {
        Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp))
        Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp))

        // LazyColumn placed in the content area for large datasets
        LazyColumn(
            modifier = Modifier
                .gridItem(ScreenArea.Content)
                .fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { item ->
                Text(item, Modifier.padding(16.dp))
            }
        }
    }
}

Kết quả

Bố cục màn hình của bạn hiện sử dụng API Grid để xác định cấu trúc trang hai chiều tổng thể, đồng thời nhúng LazyColumn vào một dải linh hoạt có kích thước minmax để tái chế các mục trong danh sách một cách hiệu quả và tránh các ngoại lệ trong thời gian chạy.

Tài nguyên khác