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.
Tuỳ chỉnh danh sách động
Thuộc Android Jetpack.
Thử dùng Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng bố cục trong ứng dụng Compose.
Bạn có thể tuỳ chỉnh các đối tượng RecyclerView
để đáp ứng các nhu cầu cụ thể của mình. Các lớp tiêu chuẩn được mô tả trong Tạo danh sách động bằng RecyclerView cung cấp tất cả các chức năng mà hầu hết các nhà phát triển đều cần. Trong nhiều trường hợp, bạn chỉ cần thiết kế chế độ xem cho mỗi trình giữ chế độ xem và viết mã để cập nhật các chế độ xem đó bằng dữ liệu thích hợp. Tuy nhiên, nếu ứng dụng của bạn có các yêu cầu cụ thể, bạn có thể sửa đổi hành vi chuẩn theo một số cách.
Tài liệu này mô tả một số tuỳ chỉnh có thể áp dụng.
Sửa đổi bố cục
RecyclerView
sử dụng trình quản lý bố cục để đặt các mục riêng lẻ trên màn hình và xác định thời điểm dùng lại chế độ xem mục không còn hiển thị với người dùng. Để dùng lại (hoặc khôi phục) một khung hiển thị, trình quản lý bố cục có thể yêu cầu bộ chuyển đổi thay thế nội dung của khung hiển thị bằng một phần tử khác trong tập dữ liệu. Việc khôi phục chế độ xem theo cách này sẽ cải thiện hiệu suất do tránh phải tạo chế độ xem không cần thiết hoặc thực hiện các thao tác tra cứu findViewById()
tốn công sức. Thư viện hỗ trợ Android bao gồm 3 trình quản lý bố cục tiêu chuẩn, mỗi trình quản lý cung cấp nhiều lựa chọn tuỳ chỉnh:
LinearLayoutManager
: sắp xếp các mục trong danh sách một chiều. Việc sử dụng RecyclerView
với LinearLayoutManager
cung cấp chức năng như bố cục ListView
.
GridLayoutManager
: sắp xếp các mục trong lưới hai chiều, chẳng hạn như hình vuông trên bàn cờ. Việc sử dụng RecyclerView
với GridLayoutManager
cung cấp chức năng như bố cục GridView
.
StaggeredGridLayoutManager
: sắp xếp các mục trong lưới hai chiều, mỗi cột được bù một chút so với cột trước đó, chẳng hạn như các dấu sao trên cờ Hoa Kỳ.
Nếu các trình quản lý bố cục này không phù hợp với nhu cầu của bạn, thì bạn có thể tạo trình quản lý bố cục riêng bằng cách mở rộng lớp trừu tượng RecyclerView.LayoutManager
.
Thêm ảnh động cho mục
Bất cứ khi nào một mục thay đổi, RecyclerView
sẽ sử dụng một trình tạo ảnh động để thay đổi giao diện của mục đó. Trình tạo hình động này là một đối tượng mở rộng lớp RecyclerView.ItemAnimator
trừu tượng. Theo mặc định, RecyclerView
sử dụng DefaultItemAnimator
để cung cấp ảnh động. Nếu muốn cung cấp ảnh động tuỳ chỉnh, bạn có thể xác định đối tượng trình tạo ảnh động của riêng bạn bằng cách mở rộng RecyclerView.ItemAnimator
.
Bật lựa chọn mục danh sách
Thư viện recyclerview-selection
cho phép người dùng chọn các mục trong danh sách RecyclerView
bằng thao tác nhấn hoặc nhập bằng chuột. Điều này cho phép bạn duy trì quyền kiểm soát đối với bản trình bày trực quan của một mục đã chọn. Bạn cũng có thể duy trì quyền kiểm soát các chính sách kiểm soát hành vi lựa chọn, chẳng hạn như những mục nào đủ điều kiện để chọn và số lượng mục có thể chọn.
Để thêm tính năng hỗ trợ lựa chọn cho một thực thể RecyclerView
, hãy làm theo các bước sau:
- Xác định loại khoá lựa chọn để dùng, sau đó tạo một
ItemKeyProvider
.
Có 3 loại khoá chính mà bạn có thể dùng để xác định các mục đã chọn:
Để biết thông tin chi tiết về các loại khoá lựa chọn, hãy xem SelectionTracker.Builder
.
- Triển khai
ItemDetailsLookup
.
ItemDetailsLookup
cho phép thư viện lựa chọn truy cập vào thông tin về các mục RecyclerView
tuỳ theo MotionEvent
.
Đây thực sự là một nhà máy cho các thực thể ItemDetails
được sao lưu hoặc trích xuất từ một thực thể RecyclerView.ViewHolder
.
- Cập nhật các đối tượng mục
View
trong RecyclerView
để phản ánh việc người dùng chọn hay bỏ chọn các đối tượng đó.
Thư viện lựa chọn không tạo trang trí hình ảnh mặc định cho các mục đã chọn. Cung cấp thông tin này khi bạn triển khai onBindViewHolder()
.
Bạn nên làm theo phương pháp sau:
- Trong
onBindViewHolder()
, hãy gọi setActivated()
– không phải
setSelected()
– trên đối tượng View
bằng true
hoặc false
, tuỳ thuộc vào việc mục đó có được chọn hay không.
- Cập nhật việc định kiểu của chế độ xem để thể hiện trạng thái đã kích hoạt. Bạn nên dùng tài nguyên danh sách trạng thái màu để định cấu hình kiểu.
- Sử dụng
ActionMode
để cung cấp cho người dùng các công cụ thực hiện một thao tác trên lựa chọn.
Đăng ký SelectionTracker.SelectionObserver
để được thông báo khi có thay đổi về lựa chọn. Khi một lựa chọn được tạo ra lần đầu tiên, hãy bắt đầu ActionMode
để giới thiệu điều này với người dùng và cung cấp các thao tác lựa chọn cụ thể. Ví dụ: bạn có thể thêm nút xoá vào thanh ActionMode
và kết nối mũi tên quay lại trên thanh để xoá lựa chọn. Khi lựa chọn không hiển thị (nếu người dùng đã xoá lựa chọn vào lần gần đây nhất), hãy chấm dứt chế độ thao tác.
- Thực hiện mọi thao tác phụ đã được diễn giải.
Vào cuối quy trình xử lý sự kiện, thư viện có thể xác định rằng người dùng đang cố kích hoạt một mục bằng cách nhấn vào mục đó hoặc đang cố gắng kéo một mục hoặc một tập hợp các mục đã chọn. Phản ứng với những diễn giải này bằng cách đăng ký trình nghe thích hợp. Để biết thêm thông tin, hãy xem SelectionTracker.Builder
.
- Tập hợp mọi thứ bằng
SelectionTracker.Builder
.
Ví dụ sau đây cho thấy cách kết hợp các phần này:
Kotlin
var tracker = SelectionTracker.Builder(
"my-selection-id",
recyclerView,
StableIdKeyProvider(recyclerView),
MyDetailsLookup(recyclerView),
StorageStrategy.createLongStorage())
.withOnItemActivatedListener(myItemActivatedListener)
.build()
Java
SelectionTracker tracker = new SelectionTracker.Builder<>(
"my-selection-id",
recyclerView,
new StableIdKeyProvider(recyclerView),
new MyDetailsLookup(recyclerView),
StorageStrategy.createLongStorage())
.withOnItemActivatedListener(myItemActivatedListener)
.build();
Để tạo một thực thể SelectionTracker
, ứng dụng của bạn phải cung cấp cùng một RecyclerView.Adapter
mà bạn dùng để khởi chạy RecyclerView
đến SelectionTracker.Builder
. Vì lý do này, sau khi bạn tạo thực thể SelectionTracker
, hãy chèn thực thể đó vào RecyclerView.Adapter
. Nếu không, bạn sẽ không thể kiểm tra trạng thái đã chọn của một mục bằng phương thức onBindViewHolder()
.
- Đưa lựa chọn vào các sự kiện trong vòng đời hoạt động.
Để duy trì trạng thái lựa chọn xuyên suốt các sự kiện trong vòng đời hoạt động, ứng dụng của bạn phải gọi các phương thức onSaveInstanceState()
và onRestoreInstanceState()
của trình theo dõi lựa chọn từ phương thức onSaveInstanceState()
và onRestoreInstanceState()
tương ứng của hoạt động. Ứng dụng của bạn cũng phải cung cấp một mã nhận dạng (ID) lựa chọn duy nhất cho hàm khởi tạo SelectionTracker.Builder
. Mã nhận dạng này là bắt buộc vì một hoạt động hoặc một mảnh có thể có nhiều danh sách riêng biệt và lựa chọn được. Tất cả các danh sách này đều phải được duy trì ở trạng thái đã lưu.
Tài nguyên khác
Hãy xem các tài liệu tham khảo sau đây để biết thêm thông tin.
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-21 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-21 UTC."],[],[],null,["# Customize a dynamic list\nPart of [Android Jetpack](/jetpack).\n=============================================================\n\nTry the Compose way \nJetpack Compose is the recommended UI toolkit for Android. Learn how to work with layouts in Compose. \n[Lazy Lists and Grids →](/jetpack/compose/lists#lazy) \n\nYou can customize\n[RecyclerView](/reference/androidx/recyclerview/widget/RecyclerView)\nobjects to meet your specific needs. The standard classes described in\n[Create dynamic lists with\nRecyclerView](/guide/topics/ui/layout/recyclerview) provide all the functionality that most developers need. In\nmany cases, you only need to design the view for each view holder and write the\ncode to update those views with the appropriate data. However, if your app has\nspecific requirements, you can modify the standard behavior in a number of ways.\nThis document describes some of the possible customizations.\n\nModify the layout\n-----------------\n\n`RecyclerView` uses a layout manager to position the individual\nitems on the screen and to determine when to reuse item views that are no longer\nvisible to the user. To reuse---or *recycle* ---a view, a layout\nmanager might ask the adapter to replace the contents of the view with a\ndifferent element from the dataset. Recycling views this way improves\nperformance by avoiding the creation of unnecessary views or performing\nexpensive\n[findViewById()](/reference/android/app/Activity#findViewById(int))\nlookups. The Android Support Library includes three standard layout managers,\nach of which offers many customization options:\n\n- [LinearLayoutManager](/reference/androidx/recyclerview/widget/LinearLayoutManager): arranges the items in a one-dimensional list. Using a `RecyclerView` with `LinearLayoutManager` provides functionality like a [ListView](/reference/android/widget/ListView) layout.\n- [GridLayoutManager](/reference/androidx/recyclerview/widget/GridLayoutManager): arranges the items in a two-dimensional grid, like the squares on a checkerboard. Using a `RecyclerView` with `GridLayoutManager` provides functionality like a [GridView](/reference/android/widget/GridView) layout.\n- [StaggeredGridLayoutManager](/reference/androidx/recyclerview/widget/StaggeredGridLayoutManager): arranges the items in a two-dimensional grid, with each column slightly offset from the one before, like the stars on an American flag.\n\nIf these layout managers don't suit your needs, you can create your own by\nextending the\n[RecyclerView.LayoutManager](/reference/androidx/recyclerview/widget/RecyclerView.LayoutManager)\nabstract class.\n\nAdd item animations\n-------------------\n\nWhenever an item changes, `RecyclerView` uses an *animator*\nto change its appearance. This animator is an object that extends the abstract\n[RecyclerView.ItemAnimator](/reference/androidx/recyclerview/widget/RecyclerView.ItemAnimator)\nclass. By default, the `RecyclerView` uses\n[DefaultItemAnimator](/reference/androidx/recyclerview/widget/DefaultItemAnimator)\nto provide the animation. If you want to provide custom animations, you can\ndefine your own animator object by extending\n`RecyclerView.ItemAnimator`.\n\nEnable list-item selection\n--------------------------\n\nThe\n[`recyclerview-selection`](/reference/androidx/recyclerview/selection/package-summary)\nlibrary lets users select items in a `RecyclerView` list using touch\nor mouse input. This lets you retain control over the visual presentation of a\nselected item. You can also retain control over policies controlling selection\nbehavior, such as which items are eligible for selection and how many items can\nbe selected.\n\nTo add selection support to a `RecyclerView` instance, follow\nthese steps:\n\n1. Determine which selection key type to use, then build an [`ItemKeyProvider`](/reference/androidx/recyclerview/selection/ItemKeyProvider).\n\n There are three key types you can use to identify selected items:\n - [Parcelable](/reference/android/os/Parcelable) and its subclasses, like [Uri](/reference/android/net/Uri)\n - [String](/reference/java/lang/String)\n - [Long](/reference/java/lang/Long)\n\n For detailed information about selection-key types, see\n [SelectionTracker.Builder](/reference/androidx/recyclerview/selection/SelectionTracker.Builder).\n2. Implement [ItemDetailsLookup](/reference/androidx/recyclerview/selection/ItemDetailsLookup).\n3. `ItemDetailsLookup` lets the selection library access information about `RecyclerView` items given a [MotionEvent](/reference/android/view/MotionEvent). It is effectively a factory for [`ItemDetails`](/reference/androidx/recyclerview/selection/ItemDetailsLookup.ItemDetails) instances that are backed up by, or extracted from, a [RecyclerView.ViewHolder](/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder) instance.\n4. Update item [View](/reference/android/view/View) objects in the `RecyclerView` to reflect whether the user selects or unselects them.\n\n The selection library doesn't provide a default visual decoration for the\n selected items. Provide this when you implement\n [onBindViewHolder()](/reference/androidx/recyclerview/widget/RecyclerView.Adapter#onBindViewHolder(VH, int)).\n We recommend the following approach:\n - In `onBindViewHolder()`, call [setActivated()](/reference/android/view/View#setActivated(boolean))---**not** [setSelected()](/reference/android/view/View#setSelected(boolean))---on the `View` object with `true` or `false`, depending on whether the item is selected.\n - Update the styling of the view to represent the activated status. We recommend using a [color state\n list resource](/guide/topics/resources/color-list-resource) to configure the styling.\n5. Use [ActionMode](/reference/androidx/appcompat/view/ActionMode) to provide the user with tools to perform an action on the selection.\n6. Register a [SelectionTracker.SelectionObserver](/reference/androidx/recyclerview/selection/SelectionTracker.SelectionObserver) to be notified when a selection changes. When a selection is first created, start `ActionMode` to present this to the user and provide selection-specific actions. For example, you can add a delete button to the `ActionMode` bar and connect the back arrow on the bar to clear the selection. When the selection becomes empty---if the user clears the selection the last time---terminate action mode.\n7. Perform any interpreted secondary actions.\n8. At the end of the event processing pipeline, the library might determine that the user is attempting to activate an item, by tapping it, or is attempting to drag an item or set of selected items. React to these interpretations by registering the appropriate listener. For more information, see [SelectionTracker.Builder](/reference/androidx/recyclerview/selection/SelectionTracker.Builder).\n9. Assemble everything with `SelectionTracker.Builder`.\n10. The following example shows how to put these pieces together: \n\n### Kotlin\n\n```kotlin\n var tracker = SelectionTracker.Builder(\n \"my-selection-id\",\n recyclerView,\n StableIdKeyProvider(recyclerView),\n MyDetailsLookup(recyclerView),\n StorageStrategy.createLongStorage())\n .withOnItemActivatedListener(myItemActivatedListener)\n .build()\n \n```\n\n### Java\n\n```java\n SelectionTracker tracker = new SelectionTracker.Builder\u003c\u003e(\n \"my-selection-id\",\n recyclerView,\n new StableIdKeyProvider(recyclerView),\n new MyDetailsLookup(recyclerView),\n StorageStrategy.createLongStorage())\n .withOnItemActivatedListener(myItemActivatedListener)\n .build();\n \n```\n11. To build a [SelectionTracker](/reference/androidx/recyclerview/selection/SelectionTracker) instance, your app must supply the same [RecyclerView.Adapter](/reference/androidx/recyclerview/widget/RecyclerView.Adapter) that you use to initialize `RecyclerView` to `SelectionTracker.Builder`. For this reason, after you create the `SelectionTracker` instance, inject it into your `RecyclerView.Adapter`. Otherwise, you can't check an item's selected status from the `onBindViewHolder()` method.\n12. Include selection in the [activity\n lifecycle](/guide/components/activities/activity-lifecycle) events.\n13. To preserve selection state across the activity lifecycle events, your app must call the selection tracker's [onSaveInstanceState()](/reference/androidx/recyclerview/selection/SelectionTracker#onSaveInstanceState(android.os.Bundle)) and [onRestoreInstanceState()](/reference/androidx/recyclerview/selection/SelectionTracker#onRestoreInstanceState(android.os.Bundle)) methods from the activity's [onSaveInstanceState()](/reference/android/app/Activity#onSaveInstanceState(android.os.Bundle)) and [onRestoreInstanceState()](/reference/android/app/Activity#onRestoreInstanceState(android.os.Bundle)) methods, respectively. Your app must also supply a unique selection ID to the `SelectionTracker.Builder` constructor. This ID is required because an activity or a fragment might have more than one distinct, selectable list, all of which need to be persisted in their saved state.\n\nAdditional resources\n--------------------\n\nSee the following references for additional information.\n\n- [Sunflower\n demo app](https://github.com/googlesamples/android-sunflower), which uses `RecyclerView`.\n- [Use\n RecyclerView to display a scrollable list](/codelabs/basic-android-kotlin-training-recyclerview-scrollable-list#0) codelab.\n- [Android\n Kotlin Fundamentals: RecyclerView fundamentals](/codelabs/kotlin-android-training-recyclerview-fundamentals) codelab."]]