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 đường kẻ (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.

Grid là một vùng chứa có cấu trúc chứ không phải 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 chế 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 một Grid có thể gây ra tình trạng tắc nghẽn hiệu suất vì tất cả các mục đều được tạo 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 trong các ô Grid. Tuy nhiên, hãy lưu ý rằng các thành phần linh hoạt (có cá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 một danh sách tải từng phần bên trong một thành phần theo dõi 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 thành phần 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 bước đo lường nội tại.

Bố cục màn hình có Tiêu đề ở trên cùng, danh sách các mục có thể cuộn trong vùng nội dung chính và 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à một LazyColumn được nhúng cho nội dung.

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

  • Sử dụng danh sách trì hoãn thay vì các 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 trì hoãn (thường là LazyColumn hoặc LazyRow) vào bên trong các ô lưới cụ thể thay vì tạo các 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 là 1.000 bản nhạc.
  • Sử dụng tính năng theo dõi kích thước MinMax cho danh sách tải từng phần: Vì LazyColumnLazyRow 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 thành phần tải từng phần lưu trữ các thành phần linh hoạt để bỏ qua các phép đo nội tại một cách an toàn.

Nguyên liệu

  • Grid: Bố cục có thể 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ách sử dụng các hàng và cột rõ ràng.
  • LazyColumn: Danh sách cuộn theo chiều dọc chỉ tạo và tái chế các mục hiện đang hiển thị trên màn hình.
  • GridTrackSize.MinMax: Theo dõi thuộc tính kích thước xác định các ranh giới linh hoạt (minmax) để lưu trữ an toàn các thành phần có tải trễ mà không kích hoạt sự cố đo lường thời gian chạy.
  • gridItem: Tiện ích mở rộng Modifier Compose 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ên bên trong Grid.

Các bước

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

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

Tạo một lớp enum để biểu thị các vùng riêng biệt trong bố cục màn hình và xác định một lambda GridConfigurationScope cho các thành phần theo dõi bố cục và các 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 lười biếng để 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 Lưới

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 (HeaderFooter) rồi định vị các thành phần đó bằng Modifier.gridItem() cùng với giá trị nhận dạng khu vực 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 cách dùng Modifier.gridItem(ScreenArea.Content). Vì thành phần nội dung được định cấu hình bằng minmax(0.dp, 1.fr) ở 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 phương diện 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ả

Giờ đây, bố cục màn hình của bạn sử dụng API Grid để xác định cấu trúc trang tổng thể hai chiều, đồng thời nhúng LazyColumn vào một thành phần theo 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 trường hợp ngoại lệ trong thời gian chạy.

Tài nguyên khác