Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
RecyclerView là một thành phần View giúp dễ dàng hiển thị hiệu quả các tập dữ liệu lớn. Thay vì tạo khung hiển thị cho từng mục trong tập dữ liệu, RecyclerView cải thiện hiệu suất của ứng dụng bằng cách duy trì một nhóm nhỏ các khung hiển thị và sử dụng lại các khung hiển thị đó khi bạn di chuyển qua các mục.
Trong Compose, bạn có thể dùng Danh sách Lazy để thực hiện việc tương tự. Trang này mô tả cách bạn có thể di chuyển việc triển khai RecyclerView để sử dụng Danh sách lười biếng trong Compose.
Các bước di chuyển
Để di chuyển việc triển khai RecyclerView sang Compose, hãy làm theo các bước sau:
Ghi chú hoặc xoá RecyclerView khỏi hệ phân cấp giao diện người dùng và thêm ComposeView để thay thế nếu chưa có thành phần nào trong hệ phân cấp. Đây là vùng chứa cho danh sách Lazy mà bạn sẽ thêm:
Xác định loại thành phần kết hợp Danh sách trì hoãn mà bạn cần dựa trên trình quản lý bố cục của RecyclerView (xem bảng bên dưới). Thành phần kết hợp mà bạn chọn sẽ là thành phần kết hợp cấp cao nhất của ComposeView mà bạn đã thêm ở bước trước.
LayoutManager
Thành phần kết hợp
LinearLayoutManager
LazyColumn hoặc LazyRow
GridLayoutManager
LazyVerticalGrid hoặc LazyHorizontalGrid
StaggeredGridLayoutManager
LazyVerticalStaggeredGrid hoặc LazyHorizontalStaggeredGrid
// recyclerView.layoutManager = LinearLayoutManager(context)composeView.setContent{LazyColumn(Modifier.fillMaxSize()){// We use a LazyColumn since the layout manager of the RecyclerView is a vertical LinearLayoutManager}}
Tạo một thành phần kết hợp tương ứng cho từng loại khung hiển thị trong quá trình triển khai RecyclerView.Adapter. Mỗi loại khung hiển thị thường liên kết với một lớp con ViewHolder, mặc dù không phải lúc nào cũng như vậy. Các thành phần kết hợp này sẽ được dùng làm biểu thị giao diện người dùng cho nhiều loại phần tử trong danh sách của bạn:
@ComposablefunListItem(data:MyData,modifier:Modifier=Modifier){Row(modifier.fillMaxWidth()){Text(text=data.name)// … other composables required for displaying `data`}}
Logic trong các phương thức onCreateViewHolder() và onBindViewHolder() của RecyclerView.Adapter sẽ được thay thế bằng các thành phần kết hợp này và trạng thái mà bạn cung cấp cho chúng. Trong Compose, không có sự tách biệt giữa việc tạo một thành phần kết hợp cho một mục và liên kết dữ liệu vào thành phần đó – những khái niệm này được kết hợp với nhau.
Trong khe content của Danh sách lười (tham số lambda ở cuối), hãy dùng hàm items() (hoặc một hàm nạp chồng tương đương) để lặp lại dữ liệu cho danh sách của bạn. Trong hàm lambda itemContent, hãy gọi mục thành phần kết hợp thích hợp cho dữ liệu của bạn:
RecyclerView có khái niệm về ItemDecoration. Bạn có thể dùng ItemDecoration để thêm một bản vẽ đặc biệt cho các mục trong danh sách. Ví dụ: bạn có thể thêm ItemDecoration để thêm đường phân chia giữa các mục:
Compose không có khái niệm tương đương về thành phần trang trí mục. Thay vào đó, bạn có thể thêm mọi thành phần trang trí giao diện người dùng trong danh sách trực tiếp vào thành phần. Ví dụ: để thêm đường phân chia vào danh sách, bạn có thể dùng thành phần kết hợp Divider sau mỗi mục:
Bạn có thể đặt ItemAnimator trên RecyclerView để tạo ảnh động cho giao diện của các mục khi có thay đổi đối với trình kết nối. Theo mặc định, RecyclerView sử dụng DefaultItemAnimator. Lớp này cung cấp ảnh động cơ bản cho các sự kiện xoá, thêm và di chuyển.
Danh sách trì hoãn có một khái niệm tương tự thông qua đối tượng sửa đổi animateItemPlacement.
Hãy xem phần Ảnh động của mục để tìm hiểu thêm.
Tài nguyên khác
Để biết thêm thông tin về cách di chuyển một RecyclerView sang Compose, hãy xem các tài nguyên sau:
Danh sách và lưới: Tài liệu về cách triển khai danh sách và lưới trong Compose.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-08-22 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-08-22 UTC."],[],[],null,["[`RecyclerView`](/develop/ui/views/layout/recyclerview) is a View component that makes it easy to efficiently display\nlarge sets of data. Instead of creating views for each item in the data set,\n`RecyclerView` improves the performance of your app by keeping a small pool of\nviews and recycling through them as you scroll through those items.\n\nIn Compose, you can use [Lazy lists](/develop/ui/compose/lists#lazy) to accomplish the same thing. This page\ndescribes how you can migrate your `RecyclerView` implementation to use Lazy lists\nin Compose.\n\nMigration steps\n\nTo migrate your `RecyclerView` implementation to Compose, follow these steps:\n\n1. Comment out or remove the `RecyclerView` from your UI hierarchy and add a\n `ComposeView` to replace it if none is present in the hierarchy yet. This\n is the container for the Lazy list that you'll add:\n\n \u003cFrameLayout\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\"\u003e\n\n \u003c!-- \u003candroidx.recyclerview.widget.RecyclerView--\u003e\n \u003c!-- android:id=\"@+id/recycler_view\"--\u003e\n \u003c!-- android:layout_width=\"match_parent\"--\u003e\n \u003c!-- android:layout_height=\"match_parent /\u003e\"--\u003e\n\n \u003candroidx.compose.ui.platform.ComposeView\n android:id=\"@+id/compose_view\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\" /\u003e\n\n \u003c/FrameLayout\u003e\n\n2. Determine what type of Lazy list composable you need based on your\n `RecyclerView`'s layout manager (see table below). The composable you select\n will be the top-level composable of the `ComposeView` you added in the\n previous step.\n\n | `LayoutManager` | Composable |\n |------------------------------|--------------------------------------------------------------|\n | `LinearLayoutManager` | `LazyColumn` or `LazyRow` |\n | `GridLayoutManager` | `LazyVerticalGrid` or `LazyHorizontalGrid` |\n | `StaggeredGridLayoutManager` | `LazyVerticalStaggeredGrid` or `LazyHorizontalStaggeredGrid` |\n\n\n ```kotlin\n // recyclerView.layoutManager = LinearLayoutManager(context)\n composeView.setContent {\n LazyColumn(Modifier.fillMaxSize()) {\n // We use a LazyColumn since the layout manager of the RecyclerView is a vertical LinearLayoutManager\n }\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L79-L84\n ```\n\n \u003cbr /\u003e\n\n3. Create a corresponding composable for each view type in your\n `RecyclerView.Adapter` implementation. Each view type typically maps to a\n `ViewHolder` subclass, though this may not always be the case. These\n composables will be used as the UI representation for different types of\n elements in your list:\n\n\n ```kotlin\n @Composable\n fun ListItem(data: MyData, modifier: Modifier = Modifier) {\n Row(modifier.fillMaxWidth()) {\n Text(text = data.name)\n // ... other composables required for displaying `data`\n }\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L124-L130\n ```\n\n \u003cbr /\u003e\n\n The logic in your `RecyclerView.Adapter`'s `onCreateViewHolder()` and\n `onBindViewHolder()` methods will be replaced by these composables and the\n state that you provide them with. In Compose, there is no separation between\n creating a composable for an item and binding data into it---these concepts are\n coalesced.\n4. Within the `content` slot of the Lazy list (the trailing lambda parameter),\n use the `items()` function (or an equivalent overload) to iterate through the\n data for your list. In the `itemContent` lambda, invoke the appropriate\n composable item for your data:\n\n\n ```kotlin\n val data = listOf\u003cMyData\u003e(/* ... */)\n composeView.setContent {\n LazyColumn(Modifier.fillMaxSize()) {\n items(data) {\n ListItem(it)\n }\n }\n }https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L90-L97\n ```\n\n \u003cbr /\u003e\n\n| **Tip:** Provide additional parameters to `items()` to optimize your list: use the `key` parameter to provide a unique key for the underlying data so that scroll position will be maintained when items change, or use the `contentType` parameter to specify a content type for the underlying data (this is a similar concept to `RecyclerView`'s view types) so you can reuse item compositions more efficiently.\n\nCommon use cases\n\nItem decorations\n\n`RecyclerView` has the concept of an `ItemDecoration`, which you can use to add a\nspecial drawing for items in the list. For example, you can add an\n`ItemDecoration` to add dividers between items:\n\n\n```kotlin\nval itemDecoration = DividerItemDecoration(recyclerView.context, LinearLayoutManager.VERTICAL)\nrecyclerView.addItemDecoration(itemDecoration)https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L103-L104\n```\n\n\u003cbr /\u003e\n\nCompose does not have an equivalent concept of item decorations. Instead, you\ncan add any UI decorations in the list directly in the composition. For example,\nto add dividers to the list, you can use the `Divider` composable after each\nitem:\n\n\n```kotlin\nLazyColumn(Modifier.fillMaxSize()) {\n itemsIndexed(data) { index, d -\u003e\n ListItem(d)\n if (index != data.size - 1) {\n HorizontalDivider()\n }\n }\n}https://github.com/android/snippets/blob/7a0ebbee11495f628cf9d574f6b6069c2867232a/compose/snippets/src/main/java/com/example/compose/snippets/interop/MigrationCommonScenariosSnippets.kt#L111-L118\n```\n\n\u003cbr /\u003e\n\nItem animations\n\nAn `ItemAnimator` can be set on a `RecyclerView` to animate the appearance of\nitems as changes are made to the adapter. By default, `RecyclerView` uses\n[`DefaultItemAnimator`](/reference/androidx/recyclerview/widget/DefaultItemAnimator) which provides basic animations on remove, add, and\nmove events.\n\nLazy lists have a similar concept through the `animateItemPlacement` modifier.\nSee [Item animations](/develop/ui/compose/lists#item-animations) to learn more.\n\nAdditional resources\n\nFor more information about migrating a `RecyclerView` to Compose, see the\nfollowing resources:\n\n- [Lists and Grids](/develop/ui/compose/lists#item-animations): Documentation for how to implement lists and grids in Compose.\n- [Jetpack Compose Interop: Using Compose in a RecyclerView](https://medium.com/androiddevelopers/jetpack-compose-interop-using-compose-in-a-recyclerview-569c7ec7a583): Blog post for efficiently using Compose within a `RecyclerView`.\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [Lists and grids](/develop/ui/compose/lists)\n- [Migrate `CoordinatorLayout` to Compose](/develop/ui/compose/migrate/migration-scenarios/coordinator-layout)\n- [Other considerations](/develop/ui/compose/migrate/other-considerations)"]]