1. Trước khi bắt đầu
Khi nghĩ về những ứng dụng mà mình thường dùng trên điện thoại, bạn có thể thấy hầu hết ứng dụng đều có ít nhất một danh sách. Màn hình nhật ký cuộc gọi, ứng dụng danh bạ và ứng dụng mạng xã hội mà bạn yêu thích, tất cả đều hiển thị ít nhất một danh sách dữ liệu. Như ảnh chụp màn hình bên dưới, một số ứng dụng chỉ hiện một danh sách các từ hoặc cụm từ đơn giản. Trong khi đó, những ứng dụng khác sẽ hiện các thành phần phức tạp hơn, chẳng hạn như thẻ chứa văn bản và hình ảnh. Hiển thị danh sách dữ liệu là một trong những tác vụ giao diện người dùng phổ biến nhất trên Android, bất kể nội dung hiển thị là gì.
Android cung cấp thành phần giao diện RecyclerView
, cho phép bạn xây dựng ứng dụng với danh sách. RecyclerView
được thiết kế rất hiệu quả, có thể sử dụng cho những danh sách lớn, cho phép sử dụng lại hoặc tái chế các thành phần hiển thị (view) đã cuộn ra khỏi màn hình. Khi một phần tử trong danh sách được cuộn khỏi màn hình, RecyclerView
sẽ sử dụng lại thành phần hiển thị đó cho phần tử sắp hiện tiếp theo trong danh sách. Điều này có nghĩa rằng phần tử này sẽ chứa nội dung mới cuộn lên màn hình. Tính năng này của RecyclerView
giúp tiết kiệm rất nhiều thời gian xử lý, đồng thời giúp cuộn danh sách mượt mà hơn.
Trong chuỗi hiển thị bên dưới, bạn có thể thấy rằng một thành phần hiển thị đã được điền dữ liệu, ABC
. Sau khi thành phần hiển thị đó ra khỏi màn hình, RecyclerView
sẽ sử dụng lại thành phần đó cho dữ liệu mới, XYZ
.
Trong lớp học lập trình này, bạn sẽ tạo ứng dụng Affirmations (Lời tự động viên). Affirmations là một ứng dụng đơn giản hiển thị mười lời tự động viên tích cực dưới dạng văn bản, được hiển thị trong một danh sách cuộn. Sau đó, trong lớp học lập trình tiếp theo, bạn sẽ thực hiện thêm một bước nữa. Trong bước này, bạn sẽ thêm một hình ảnh đầy cảm hứng cho mỗi lời tự động viên và tiếp đó sẽ trau chuốt thêm phần giao diện người dùng của ứng dụng.
Điều kiện tiên quyết
- Tạo một dự án dựa trên mẫu trong Android Studio.
- Thêm tài nguyên chuỗi vào một ứng dụng.
- Định nghĩa bố cục trong XML.
- Tìm hiểu các lớp và tính kế thừa trong Kotlin (bao gồm các lớp trừu tượng).
- Kế thừa từ một lớp hiện có và ghi đè các phương thức của lớp đó.
- Sử dụng tài liệu trên trang developer.android.com dành cho các lớp học thuộc phạm vi khung ứng dụng Android.
Kiến thức bạn sẽ học được
- Cách sử dụng
RecyclerView
để hiển thị danh sách dữ liệu. - Cách tổ chức mã thành các gói
- Cách sử dụng trình chuyển đổi (adapter) với
RecyclerView
để tuỳ chỉnh giao diện của từng phần tử trong danh sách.
Sản phẩm bạn sẽ tạo ra
- Sử dụng
RecyclerView
để tạo một ứng dụng hiển thị danh sách các lời tự động viên.
Bạn cần có
- Máy tính đã cài đặt phiên bản Android Studio 4.1 trở lên.
2. Tạo dự án
Tạo dự án Hoạt động trống (Empty Activity)
Trước khi tạo dự án mới, hãy đảm bảo rằng bạn đang sử dụng Android Studio 4.1 trở lên.
- Bắt đầu tạo một dự án Kotlin mới trong Android Studio bằng mẫu Empty Activity (Hoạt động trống).
- Nhập tên ứng dụng là Affirmations vào trường Name (Tên), com.example.affirmation vào trường Package name (Tên gói) và chọn API Level 19 (API cấp 19) trong trường Minimum SDK (SDK tối thiểu).
- Nhấp vào Finish (Hoàn tất) để tạo dự án.
3. Thiết lập danh sách dữ liệu
Bước tiếp theo trong quá trình tạo ứng dụng Affirmations là thêm tài nguyên ứng dụng. Bạn sẽ thêm đoạn mã sau vào dự án của mình.
- Tài nguyên chuỗi để hiển thị các lời tự động viên trong ứng dụng.
- Nguồn dữ liệu để cung cấp danh sách các lời tự động viên cho ứng dụng của bạn.
Thêm các lời tự động viên
- Trong cửa sổ Project (Dự án), hãy mở app > res > values > strings.xml. Tệp này hiện có một tài nguyên duy nhất là tên của ứng dụng.
- Trong
strings.xml
, hãy thêm các lời tự động viên dưới dạng tài nguyên chuỗi riêng lẻ. Đặt tên cho các tài nguyên chuỗi này làaffirmation1
,affirmation2
, v.v.
Văn bản chứa các lời tự động viên
I am strong. I believe in myself. Each day is a new opportunity to grow and be a better version of myself. Every challenge in my life is an opportunity to learn from. I have so much to be grateful for. Good things are always coming into my life. New opportunities await me at every turn. I have the courage to follow my heart. Things will unfold at precisely the right time. I will be present in all the moments that this day brings.
Tệp strings.xml
hoàn chỉnh sẽ có dạng như sau.
<resources>
<string name="app_name">Affirmations</string>
<string name="affirmation1">I am strong.</string>
<string name="affirmation2">I believe in myself.</string>
<string name="affirmation3">Each day is a new opportunity to grow and be a better version of myself.</string>
<string name="affirmation4">Every challenge in my life is an opportunity to learn from.</string>
<string name="affirmation5">I have so much to be grateful for.</string>
<string name="affirmation6">Good things are always coming into my life.</string>
<string name="affirmation7">New opportunities await me at every turn.</string>
<string name="affirmation8">I have the courage to follow my heart.</string>
<string name="affirmation9">Things will unfold at precisely the right time.</string>
<string name="affirmation10">I will be present in all the moments that this day brings.</string>
</resources>
Bây giờ, sau khi thêm tài nguyên chuỗi, bạn có thể tham chiếu các tài nguyên này trong mã của mình dưới dạng R.string.affirmation1
hoặc R.string.affirmation2
.
Tạo gói mới
Việc tổ chức mã một cách hợp lý sẽ rất hữu ích cho bạn và các nhà phát triển khác trong quá trình tìm hiểu, bảo trì và mở rộng mã đó. Tương tự như cách tổ chức giấy tờ thành tệp và thư mục, bạn có thể sắp xếp mã thành tệp và gói.
Gói là gì?
- Trong Android Studio, trong cửa sổ Project (Dự án) (Android), hãy xem các tệp dự án mới của bạn trong thư mục app > java dành cho ứng dụng Affirmations. Các tệp này sẽ giống như ảnh chụp màn hình bên dưới, bao gồm ba gói, một gói dành cho mã của bạn (com.example.affirmations) và hai gói còn lại dành cho các tệp kiểm thử là (com.example.affirmations (androidTest)) và com.example.affirmations (test)).
- Lưu ý rằng các từ trong tên của gói được phân tách bằng dấu chấm.
Bạn có thể khai thác các gói theo hai cách.
- Tạo nhiều gói cho các phần mã khác nhau. Ví dụ: nhà phát triển thường tách các lớp dùng để làm việc với dữ liệu và các lớp dùng để xây dựng giao diện người dùng thành các gói khác nhau.
- Sử dụng mã từ các gói khác trong mã của bạn. Để sử dụng lớp từ các gói khác, bạn cần định nghĩa lớp này trong phần phụ thuộc của hệ thống xây dựng. Đây cũng là một phương pháp tiêu chuẩn để nhập (
import
) các gói này trong mã, nhờ đó bạn có thể sử dụng các tên rút gọn của các gói này (ví dụ:TextView
) thay vì các tên đủ điều kiện (ví dụ:android.widget.TextView
). Ví dụ: bạn đã sử dụng câu lệnhimport
cho các lớp nhưsqrt
(import kotlin.math.sqrt
) vàView
(import android.view.View
).
Trong ứng dụng Affirmations, ngoài việc nhập các lớp Android và Kotlin, bạn cũng sẽ tổ chức ứng dụng của mình trong nhiều gói. Ngay cả khi không có nhiều lớp trong ứng dụng, bạn cũng nên sử dụng gói để nhóm các lớp theo chức năng.
Đặt tên gói
Bạn có thể đặt tên bất kỳ cho một gói, miễn sao tên đó là duy nhất trên toàn cầu; nghĩa là trước đó chưa có gói nào cùng tên được xuất bản ở bất cứ nơi đâu. Do số lượng gói đã tạo rất lớn và việc có được tên gói ngẫu nhiên và độc đáo là không hề đơn giản nên các lập trình viên thường sử dụng các quy ước để dễ dàng tạo lập và hiểu rõ tên gói hơn.
- Tên gói thường được đặt theo cấu trúc từ khái quát đến cụ thể, trong đó mỗi thành phần của tên sẽ được viết bằng chữ thường và phân tách nhau bằng dấu chấm. Quan trọng: Dấu chấm chỉ là một phần của tên. Dấu này không thể hiện cho hệ phân cấp mã hoặc chỉ định cấu trúc thư mục!
- Vì các miền Internet là duy nhất trên toàn cầu nên sử dụng một miền, thường là miền của bạn hoặc miền của doanh nghiệp bạn, làm phần đầu tiên của tên gói là quy ước cần được tuân theo.
- Bạn có thể chọn tên sao cho mình có thể biết được nội dung bên trong cũng như mối liên hệ giữa các gói.
- Với các ví dụ về mã như ví dụ này, theo sau
com.example
thường là tên của ứng dụng.
Dưới đây là một số ví dụ về tên gói được định nghĩa trước và nội dung của các gói này:
kotlin.math
– Hàm toán học và hằng số.android.widget
– Các thành phần hiển thị, chẳng hạn nhưTextView
.
Tạo gói
- Trong Android Studio, trong ngăn Project (Dự án), hãy nhấp chuột phải vào app > java > com.example.affirmations rồi chọn New > Package (Mới > Gói).
- Trong cửa sổ bật lên New Package (Gói mới), hãy chú ý đến tiền tố cho tên gói đề xuất. Phần đầu tiên của tên gói đề xuất là tên của gói mà bạn đã nhấp chuột phải vào. Mặc dù tên gói không tạo nên hệ phân cấp gói, nhưng việc sử dụng lại các phần của tên sẽ cho biết mối quan hệ và cách tổ chức các nội dung trong gói!
- Trong cửa sổ bật lên, hãy gắn model vào cuối tên gói được đề xuất. Các nhà phát triển thường sử dụng model làm tên gói cho các lớp mô hình hoá (hoặc đại diện) cho dữ liệu.
- Nhấn Enter. Thao tác này sẽ tạo một gói mới trong gói com.example.affirmation (gốc). Gói mới này sẽ chứa mọi lớp liên quan đến dữ liệu được định trong ứng dụng của bạn.
Tạo lớp dữ liệu Affirmation
Trong nhiệm vụ này, bạn sẽ tạo một lớp tên là Affirmation.
Một thực thể đối tượng của Affirmation
sẽ đại diện cho một lời tự động viên và chứa mã nhận dạng tài nguyên của chuỗi chứa lời tự động viên đó.
- Nhấp chuột phải vào gói com.example.affirmation.model và chọn New > Kotlin File/Class. (Mới > Tệp/Lớp Kotlin)
- Trong cửa sổ bật lên, hãy chọn Class (Lớp) rồi nhập
Affirmation
làm tên của lớp đó. Thao tác này sẽ tạo một tệp mới có tên làAffirmation.kt
trong góimodel
. - Thiết lập
Affirmation
thành lớp dữ liệu bằng cách thêm từ khoádata
trước phần định nghĩa lớp. Bạn sẽ thấy lỗi xuất hiện vì phải có ít nhất một thuộc tính được định nghĩa trong một lớp dữ liệu.
Affirmation.kt
package com.example.affirmations.model
data class Affirmation {
}
Khi tạo một thực thể của Affirmation
, bạn cần truyền vào mã nhận dạng tài nguyên cho chuỗi chứa lời tự động viên đó. Mã nhận dạng tài nguyên là một số nguyên.
- Hãy thêm một tham số kiểu số nguyên
val
stringResourceId
vào hàm khởi tạo của lớpAffirmation
. Thao tác này sẽ giúp khắc phục lỗi ở trên.
package com.example.affirmations.model
data class Affirmation(val stringResourceId: Int)
Tạo lớp đóng vai trò là nguồn dữ liệu
Dữ liệu hiển thị trong ứng dụng của bạn có thể đến từ nhiều nguồn khác nhau (ví dụ như trong dự án ứng dụng của bạn hoặc từ một nguồn bên ngoài có yêu cầu kết nối Internet để tải dữ liệu xuống). Do đó, định dạng của dữ liệu có thể không đáp ứng chính xác nhu cầu của bạn. Phần còn lại của ứng dụng không cần quan tâm đến nguồn gốc cũng như định dạng ban đầu của dữ liệu. Bạn có thể và nên đưa phần chuẩn bị dữ liệu này vào trong một lớp Datasource
riêng biệt để chuẩn bị dữ liệu cho ứng dụng.
Chuẩn bị dữ liệu là một quan tâm riêng nên hãy đặt lớp Datasource
vào một gói data (dữ liệu) riêng.
- Trong Android Studio, trong cửa sổ Project (Dự án), hãy nhấp chuột phải vào app > java > com.example.affirmations và chọn New > Package (Mới > Gói).
- Nhập
data
làm phần tên cuối cùng của gói. - Nhấp chuột phải vào gói
data
rồi chọn New > Kotlin File/Class (Mới > Tệp/Lớp Kotlin). - Nhập tên lớp là
Datasource
. - Bên trong lớp
Datasource
, hãy tạo một hàm tên làloadAffirmations()
.
Hàm loadAffirmations()
cần trả về danh sách Affirmations
. Bạn thực hiện điều này bằng cách tạo một danh sách và điền vào một thực thể Affirmation
cho mỗi chuỗi tài nguyên.
- Khai báo kiểu trả về của phương thức
loadAffirmations()
làList<Affirmation>
. - Trong thân hàm
loadAffirmations()
, hãy thêm câu lệnhreturn
. - Sau từ khoá
return
, hãy gọilistOf<>()
để tạoList
. - Trong cặp dấu nhọn
<>
, hãy chỉ định kiểu của các phần tử trong danh sách làAffirmation
. Nếu cần, hãy nhậpcom.example.affirmations.model.Affirmation
. - Bên trong dấu ngoặc đơn, hãy tạo một
Affirmation
, truyền vào mã nhận dạng tài nguyênR.string.affirmation1
như hình bên dưới.
Affirmation(R.string.affirmation1)
- Thêm các đối tượng
Affirmation
còn lại vào danh sách tất cả lời tự động viên, phân tách nhau bằng dấu phẩy. Mã hoàn chỉnh sẽ có dạng như sau.
Datasource.kt
package com.example.affirmations.data
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
class Datasource {
fun loadAffirmations(): List<Affirmation> {
return listOf<Affirmation>(
Affirmation(R.string.affirmation1),
Affirmation(R.string.affirmation2),
Affirmation(R.string.affirmation3),
Affirmation(R.string.affirmation4),
Affirmation(R.string.affirmation5),
Affirmation(R.string.affirmation6),
Affirmation(R.string.affirmation7),
Affirmation(R.string.affirmation8),
Affirmation(R.string.affirmation9),
Affirmation(R.string.affirmation10)
)
}
}
[Không bắt buộc] Hiển thị kích thước của danh sách Lời tự động viên trong TextView
Để kiểm tra xem bạn có thể tạo danh sách các lời tự động viên hay không, bạn có thể gọi loadAffirmations()
và hiển thị kích thước của danh sách lời tự động viên được trả về trong TextView
đi kèm với mẫu ứng dụng Hoạt động trống (Empty Activity).
- Trong
layouts/activity_main.xml
, hãy cung cấp giá trịid
củatextview
choTextView
đi kèm với mẫu ứng dụng của bạn. - Trong
MainActivity
, trong phương thứconCreate()
nằm sau mã hiện tại, hãy tham chiếu đếntextview
.
val textView: TextView = findViewById(R.id.textview)
- Sau đó, hãy thêm mã để tạo và hiển thị kích thước của danh sách lời tự động viên. Tạo
Datasource
, gọi hàmloadAffirmations()
, lấy kích thước của danh sách trả về, chuyển đổi kích thước này thành một chuỗi và gán giá trị đó vào thuộc tínhtext
củatextView
.
textView.text = Datasource().loadAffirmations().size.toString()
- Chạy ứng dụng. Màn hình sẽ xuất hiện như bên dưới.
- Xoá mã mà bạn vừa thêm trong
MainActivity
.
4. Thêm RecyclerView vào ứng dụng của bạn
Trong nhiệm vụ này, bạn sẽ thiết lập một RecyclerView
để hiển thị danh sách Affirmations
.
Quá trình tạo và sử dụng RecyclerView
sẽ liên quan đến một số thành phần. Bạn có thể xem đây như một quá trình phân công lao động. Sơ đồ dưới đây sẽ cung cấp một cái nhìn tổng quan và bạn sẽ tìm hiểu chi tiết hơn về những thành phần này trong quá trình triển khai.
- phần tử (item) – Một phần tử dữ liệu trong danh sách để hiển thị. Đại diện cho một đối tượng
Affirmation
trong ứng dụng của bạn. - Trình chuyển đổi – Lấy dữ liệu và chuẩn bị dữ liệu này cho
RecyclerView
hiển thị. - ViewHolders – Một tập các thành phần hiển thị được
RecyclerView
sử dụng và sử dụng lại để hiển thị lời tự động viên. - RecyclerView - Các thành phần hiển thị trên màn hình
Thêm RecyclerView vào bố cục
Ứng dụng Affirmations gồm một hoạt động (activity) có tên là MainActivity
và tệp bố cục của ứng dụng này có tên là activity_main
.xml
. Trước tiên, bạn cần thêm RecyclerView
vào bố cục của MainActivity
.
- Mở
activity_main.xml
(app > res > layout > activity_main.xml) - Nếu bạn chưa sử dụng tệp này, hãy chuyển sang chế độ Phân tách.
- Xoá
TextView
.
Bố cục hiện tại sử dụng ConstraintLayout
. ConstraintLayout
là lựa chọn lý tưởng và linh hoạt khi bạn muốn bố trí nhiều thành phần hiển thị con trong một bố cục. Vì bố cục của bạn chỉ có một thành phần hiển thị con, RecyclerView
, bạn có thể chuyển sang một ViewGroup
đơn giản hơn gọi là FrameLayout
, thường dùng để lưu giữ một thành phần hiển thị con duy nhất.
- Trong XML, hãy thay thế
ConstraintLayout
bằngFrameLayout
. Bố cục đã hoàn chỉnh sẽ có dạng như sau.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</FrameLayout>
- Chuyển sang chế độ xem Design (Thiết kế).
- Trong Palette (Bảng chế độ xem), hãy chọn Containers (Vùng chứa) và tìm RecyclerView.
- Kéo RecyclerView vào bố cục.
- Đọc thông tin trong cửa sổ bật lên Add Project Dependency (Thêm phần phụ thuộc dự án) nếu cửa sổ này xuất hiện, sau đó nhấp vào OK. (Nếu cửa sổ bật lên không xuất hiện thì bạn không cần làm gì.)
- Hãy đợi Android Studio hoàn tất và
RecyclerView
sẽ xuất hiện trong bố cục. - Nếu cần, hãy thay đổi thuộc tính
layout_width
vàlayout_height
củaRecyclerView
thànhmatch_parent
đểRecyclerView
có thể lấp đầy toàn bộ màn hình. - Đặt mã nhận dạng tài nguyên của
RecyclerView
thànhrecycler_view
.
RecyclerView
hỗ trợ hiển thị các phần tử theo nhiều cách khác nhau, chẳng hạn như dưới dạng danh sách tuyến tính hoặc dạng lưới. Việc sắp xếp các phần tử sẽ do LayoutManager
xử lý. Khung ứng dụng Android sẽ cung cấp các trình quản lý bố cục cho các bố cục thành phần cơ bản. Ứng dụng Affirmations hiển thị các phần tử dưới dạng danh sách theo chiều dọc, nhờ vậy bạn có thể sử dụng LinearLayoutManager
.
- Chuyển về chế độ xem Code (Mã). Trong mã XML, bên trong phần tử
RecyclerView
, hãy thiết lập thuộc tính cho trình quản lý bố cục củaRecyclerView
thànhLinearLayoutManager
, như minh hoạ bên dưới.
app:layoutManager="LinearLayoutManager"
Để có thể cuộn dọc danh sách các phần tử có kích thước dài hơn màn hình, bạn cần thêm một thanh cuộn dọc.
- Bên trong
RecyclerView
, hãy thêm thuộc tínhandroid:scrollbars
và thiết lập giá trị thànhvertical
.
android:scrollbars="vertical"
Bố cục XML cuối cùng sẽ có dạng như sau:
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager" />
</FrameLayout>
- Chạy ứng dụng của bạn.
Đảm bảo không gặp bất kỳ vấn đề nào trong quá trình biên dịch và chạy ứng dụng của bạn. Tuy nhiên, bạn chỉ thấy ứng dụng hiển thị nền trắng do thiếu một đoạn mã quan trọng. Hiện tại, bạn đã có nguồn dữ liệu và đã thêm RecyclerView
vào bố cục, nhưng RecyclerView
không có thông tin về cách hiển thị các đối tượng Affirmation
.
Triển khai Trình chuyển đổi cho RecyclerView
Ứng dụng của bạn cần biết cách để lấy dữ liệu từ Datasource
và định dạng dữ liệu này để mỗi Affirmation
đều được hiển thị dưới dạng một phần tử trong RecyclerView
.
Trình chuyển đổi là một mẫu thiết kế cho phép điều chỉnh dữ liệu để RecyclerView
có thể dùng được. Trong trường hợp này, bạn cần một trình chuyển đổi để lấy thực thể của Affirmation
từ danh sách trả về của hàm loadAffirmations()
. Sau đó, chuyển thực thể này thành một thành phần hiển thị phần tử trong danh sách (list item view). Nhờ đó, thành phần này mới có thể hiển thị trong RecyclerView.
Khi chạy ứng dụng, RecyclerView
sẽ sử dụng trình chuyển đổi này để tìm cách hiện dữ liệu trên màn hình. RecyclerView
yêu cầu trình chuyển đổi tạo một thành phần hiển thị phần tử trong danh sách mới (new list item view) cho phần tử dữ liệu đầu tiên trong danh sách của bạn. Khi đã tạo thành phần hiển thị này, RecyclerView sẽ yêu cầu trình chuyển đổi cung cấp dữ liệu để vẽ phần tử này. Quá trình này lặp lại cho đến khi RecyclerView
không cần thêm thành phần hiển thị nào nữa để lấp đầy màn hình. Nếu màn hình chỉ cho phép hiện cùng lúc 3 thành phần hiển thị phần tử trong danh sách, thì RecyclerView
chỉ yêu cầu trình chuyển đổi chuẩn bị 3 thành phần hiển thị đó (thay vì chuẩn bị tất cả 10 thành phần hiển thị).
Trong bước này, bạn sẽ tạo một trình chuyển đổi có khả năng điều chỉnh thực thể của đối tượng Affirmation
để có thể hiển thị thực thể đó trong RecyclerView
.
Tạo Trình chuyển đổi
Trình chuyển đổi có nhiều thành phần khác nhau và bạn sẽ viết khá nhiều mã phức tạp hơn so với những gì bạn đã viết từ đầu khoá học này. Bạn đừng lo lắng nếu chưa hiểu đầy đủ các chi tiết vào lúc đầu. Sau khi hoàn thành toàn bộ ứng dụng này bằng RecyclerView
, bạn sẽ hiểu rõ hơn về cách thức khớp nối lẫn nhau giữa các thành phần này. Bạn cũng có thể sử dụng lại mã này làm cơ sở để tạo các ứng dụng trong tương lai với RecyclerView
.
Tạo bố cục cho các phần tử (item)
Mỗi phần tử trong RecyclerView
có bố cục riêng được định nghĩa trong một tệp bố cục riêng. Vì bạn chỉ muốn hiển thị một chuỗi nên có thể sử dụng TextView
cho bố cục thành phần (item layout) của mình.
- Trong res > layout, hãy tạo một File (Tệp) trống có tên là
list_item.xml
. - Mở
list_item.xml
ở chế độ xem Code (Mã). - Thêm một
TextView
vớiid
item_title
. - Thêm
wrap_content
cholayout_width
vàlayout_height
, như minh hoạ trong mã bên dưới.
Lưu ý rằng bạn không cần một ViewGroup
xung quanh bố cục của mình. Lý do là bố cục thành phần của danh sách này sẽ được tăng cường sau này và được thêm vào như một thành phần con của RecyclerView
.
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Ngoài ra, có thể bạn đã sử dụng chức năng File > New > Layout Resource File (Tệp > Mới > Tệp tài nguyên bố cục), trong đó File name (Tên tệp) là list_item.xml
và Root element (Phần tử gốc) là TextView
. Tiếp đó, hãy cập nhật mã đã tạo để khớp với mã ở trên.
Tạo lớp ItemAdapter
- Trong ngăn Project (Dự án) trong Android Studio, hãy nhấp chuột phải vào app > java > com.example.affirmations rồi chọn New > Package (Mới > Gói).
- Nhập
adapter
làm phần tên cuối cùng của gói. - Nhấp chuột phải vào gói
adapter
rồi chọn New > Kotlin File/Class (Mới > Tệp/Lớp Kotlin). - Nhập tên lớp là
ItemAdapter
, hoàn tất và tệpItemAdapter.kt
sẽ mở ra.
Bạn cần thêm một tham số vào hàm khởi tạo của ItemAdapter
. Nhờ đó, bạn có thể truyền danh sách lời tự động viên vào trình chuyển đổi.
- Thêm một tham số vào hàm khởi tạo
ItemAdapter
. Đó là mộtval
có tên làdataset
thuộc kiểuList<Affirmation>
. NhậpAffirmation
, nếu cần thiết. - Do
dataset
chỉ được sử dụng trong lớp này, hãy chỉ định biến này thànhprivate
.
ItemAdapter.kt
import com.example.affirmations.model.Affirmation
class ItemAdapter(private val dataset: List<Affirmation>) {
}
ItemAdapter
cần thông tin về cách phân giải (resolve) tài nguyên chuỗi. Thông tin này và những thông tin khác về ứng dụng sẽ được lưu trữ trong một thực thể đối tượng Context
mà bạn có thể truyền vào một thực thể của ItemAdapter
.
- Thêm một tham số vào hàm khởi tạo
ItemAdapter
. Đó là mộtval
có tên làcontext
thuộc kiểuContext
. Đặt tham số này làm tham số đầu tiên trong hàm khởi tạo.
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {
}
Tạo ViewHolder
RecyclerView
không tương tác trực tiếp với thành phần hiển thị phần tử (item view) nhưng lại tương tác với ViewHolders
. ViewHolder
đại diện cho một thành phần hiển thị phần tử trong danh sách trong RecyclerView
và có thể được sử dụng lại khi có thể. Thực thể của ViewHolder
lưu giữ các tham chiếu đến từng thành phần hiển thị trong bố cục thành phần của danh sách (do đó có tên là "trình lưu giữ thành phần hiển thị"). Bằng cách này, bạn có thể dễ dàng cập nhật dữ liệu mới cho thành phần hiển thị phần tử trong danh sách. Trình lưu giữ thành phần hiển thị (view holder) cũng bổ sung thông tin mà RecyclerView
sử dụng để di chuyển các thành phần hiển thị xung quanh màn hình một cách hiệu quả.
- Bên trong lớp
ItemAdapter
, trước dấu ngoặc nhọn đóng choItemAdapter
, hãy tạo một lớpItemViewHolder
.
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {
class ItemViewHolder()
}
- Quá trình định nghĩa một lớp bên trong một lớp khác được gọi là quá trình tạo lớp lồng nhau (nested class).
ItemViewHolder
chỉ đượcItemAdapter
sử dụng, việc tạo lớp này bên trongItemAdapter
cho thấy mối quan hệ này. Điều này không bắt buộc nhưng sẽ giúp các nhà phát triển khác hiểu được cấu trúc chương trình của bạn.
- Thêm tham số
private
val
view
thuộc kiểuView
vào hàm khởi tạo của lớpItemViewHolder
. - Thiết lập
ItemViewHolder
làm lớp con củaRecyclerView.ViewHolder
và truyền tham sốview
vào hàm khởi tạo của lớp cha. - Bên trong
ItemViewHolder
, định nghĩa thuộc tínhval
textView
có kiểuTextView
. Gán thuộc tính này bằng thành phần hiển thị có mã nhận dạngitem_title
đã định nghĩa tronglist_item
.xml
.
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
}
Ghi đè phương thức của trình chuyển đổi
- Thêm mã để mở rộng lớp
ItemAdapter
từ lớp trừu tượngRecyclerView.Adapter
. Chỉ địnhItemAdapter.ItemViewHolder
làm kiểu trình lưu giữ thành phần hiển thị (view holder) trong cặp dấu nhọn (<>).
class ItemAdapter(
private val context: Context,
private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
}
Bạn sẽ thấy lỗi xuất hiện vì bạn cần triển khai một số phương thức trừu tượng của RecyclerView.Adapter
.
- Đặt con trỏ lên
ItemAdapter
rồi nhấn Command+I (Control+I trên Windows). Thao tác này sẽ hiển thị danh sách các phương thức bạn cần triển khai:getItemCount()
,onCreateViewHolder()
vàonBindViewHolder()
.
- Chọn cả ba phương thức này bằng cách sử dụng Shift+nhấp chuột và nhấp vào OK.
Thao tác này sẽ tạo các đoạn mã sơ khai gồm các tham số chính xác cho 3 phương thức như bên dưới.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
TODO("Not yet implemented")
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
TODO("Not yet implemented")
}
Bạn sẽ không thấy xuất hiện lỗi nào nữa. Tiếp theo, bạn cần triển khai các phương thức này để thực hiện chính xác các yêu cầu của ứng dụng.
Triển khai phương thức getItemCount()
Phương thức getItemCount()
cần trả về kích thước của tập dữ liệu. Dữ liệu của ứng dụng nằm trong thuộc tính dataset
bạn đang truyền vào hàm khởi tạo ItemAdapter
. Bạn có thể lấy kích thước của tập dữ liệu bằng thuộc tính size
.
- Thay thế
getItemCount()
bằng mã sau:
override fun getItemCount() = dataset.size
Dưới đây là cách viết ngắn gọn hơn:
override fun getItemCount(): Int {
return dataset.size
}
Triển khai phương thức onCreateViewHolder()
Trình quản lý bố cục gọi phương thức onCreateViewHolder()
để tạo trình lưu giữ thành phần hiển thị mới choRecyclerView
(nếu hiện tại không có trình lưu giữ thành phần hiển thị nào có thể sử dụng lại được). Hãy nhớ rằng trình lưu giữ thành phần hiển thị (view holder) đại diện cho một thành phần hiển thị phần tử trong danh sách (list item view).
Phương thức onCreateViewHolder()
có hai tham số và trả về một ViewHolder
mới.
- Tham số
parent
, là nhóm thành phần hiển thị (view group) chứa thành phần hiển thị phần tử trong danh sách mới (phần tử con). Thành phần mẹ ở đây làRecyclerView
. - Tham số
viewType
trở nên quan trọng khi có nhiều kiểu thành phần hiển thị phần tử (item view types) trong cùngRecyclerView
. Nếu có các bố cục thành phần danh sách (list item layout) khác nhau hiển thị trongRecyclerView
thì sẽ có các kiểu thành phần hiển thị phần tử khác nhau. Bạn chỉ có thể tái sử dụng các thành phần hiển thị có cùng kiểu thành phần hiển thị phần tử. Trong trường hợp của bạn, chỉ có một bố cục thành phần danh sách và một kiểu thành phần hiển thị phần tử nên bạn không cần lo lắng về tham số này.
- Trong phương thức
onCreateViewHolder()
, lấy một thực thể củaLayoutInflater
từ ngữ cảnh đã cung cấp (context
củaparent
). Trình tăng cường bố cục (layout inflater) biết cách để tăng cường bố cục XML thành một hệ phân cấp các đối tượng của thành phần hiển thị.
val adapterLayout = LayoutInflater.from(parent.context)
- Sau khi đã có thực thể của đối tượng
LayoutInflater
, hãy thêm một dấu chấm, theo sau là một lệnh gọi phương thức khác để tăng cường thành phần hiển thị phần tử trong danh sách thực tế. Truyền vào mã nhận dạng tài nguyên bố cục XMLR.layout.list_item
và nhóm thành phần hiển thịparent
. Đối số boolean thứ ba làattachToRoot
. Đối số này cần mang giá trịfalse
bởi vìRecyclerView
sẽ thêm phần tử này vào hệ phân cấp thành phần hiển thị vào thời điểm thích hợp.
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
Bây giờ, adapterLayout
lưu giữ một tham chiếu đến thành phần hiển thị phần tử trong danh sách (từ đó chúng ta có thể tìm thấy
các thành phần hiển thị con như TextView
sau này).
- Trong
onCreateViewHolder()
, hãy trả về một thực thểItemViewHolder
mới có thành phần hiển thị gốc làadapterLayout
.
return ItemViewHolder(adapterLayout)
Dưới đây là toàn bộ mã cho onCreateViewHolder()
cho đến thời điểm này.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
// create a new view
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return ItemViewHolder(adapterLayout)
}
Triển khai phương thức onBindViewHolder()
Phương thức cuối cùng bạn cần ghi đè là onBindViewHolder()
. Trình quản lý bố cục sẽ gọi phương thức này để thay thế nội dung của thành phần hiển thị phần tử trong danh sách.
Phương thức onBindViewHolder()
có hai tham số, trong đó tham số ItemViewHolder
được tạo trước đó bằng phương thức onCreateViewHolder()
và phương thức int
đại diện cho phần tử hiện tại position
trong danh sách. Trong phương thức này, bạn sẽ tìm thấy đối tượng Affirmation
phù hợp từ tập dữ liệu dựa trên vị trí.
- Bên trong
onBindViewHolder()
, tạo mộtval
item
và lấy phần tử này tạiposition
cho trước trongdataset
.
val item = dataset[position]
Cuối cùng, bạn cần cập nhật tất cả thành phần hiển thị được trình lưu giữ chế độ xem tham chiếu đến để phản ánh đúng dữ liệu của phần tử này. Trong trường hợp này, chỉ có một thành phần hiển thị: TextView
trong ItemViewHolder
. Thiết lập văn bản của TextView
để hiển thị chuỗi Affirmation
cho phần tử này.
- Với một thực thể của đối tượng
Affirmation
, bạn có thể tìm thấy mã nhận dạng tài nguyên chuỗi tương ứng bằng cách gọiitem.stringResourceId
. Tuy nhiên, đây là một số nguyên và bạn cần tìm ánh xạ tới giá trị chuỗi thực.
Trong khung ứng dụng Android, bạn có thể gọi phương thức getString()
và truyền vào mã nhận dạng tài nguyên chuỗi. Giá trị trả về sẽ là giá trị chuỗi liên kết với mã tài nguyên đó. getString()
là một phương thức trong lớp Resources
và bạn có thể lấy thực thể của lớp Resources
thông qua context
.
Điều đó có nghĩa rằng bạn có thể gọi context.resources.getString()
và truyền vào một mã nhận dạng tài nguyên chuỗi. Chuỗi kết quả trả về sẽ được gán cho thuộc tính text
của textView
trong holder
ItemViewHolder
. Tóm lại, dòng mã này sẽ cập nhật trình lưu giữ thành phần hiển thị để hiển thị lời tự động viên.
holder.textView.text = context.resources.getString(item.stringResourceId)
Phương thức onBindViewHolder()
hoàn thiện sẽ có dạng như sau.
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
Sau đây là mã hoàn thiện cho trình chuyển đổi.
ItemAdapter.kt
package com.example.affirmations.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
/**
* Adapter for the [RecyclerView] in [MainActivity]. Displays [Affirmation] data object.
*/
class ItemAdapter(
private val context: Context,
private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder.
// Each data item is just an Affirmation object.
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
/**
* Create new views (invoked by the layout manager)
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
// create a new view
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return ItemViewHolder(adapterLayout)
}
/**
* Replace the contents of a view (invoked by the layout manager)
*/
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
/**
* Return the size of your dataset (invoked by the layout manager)
*/
override fun getItemCount() = dataset.size
}
Đến thời điểm hiện tại, bạn đã triển khai ItemAdapter
, bạn cần yêu cầu RecyclerView
sử dụng trình chuyển đổi này.
Chỉnh sửa MainActivity để sử dụng RecyclerView
Để hoàn thành công đoạn cuối cùng, bạn cần sử dụng lớp Datasource
và ItemAdapter
để tạo và hiển thị các phần tử trong RecyclerView
. Bạn thực hiện thao tác này trong MainActivity
.
- Mở
MainActivity.kt
. - Trong
MainActivity,
, chuyển đến phương thứconCreate()
. Chèn mã mới như được mô tả trong các bước tiếp theo sau khi gọi đếnsetContentView(R.layout.activity_main).
- Tạo một thực thể của
Datasource
và gọi phương thứcloadAffirmations()
trên thực thể đó. Lưu danh sách lời tự động viên được trả về trong một biếnval
có tênmyDataset
.
val myDataset = Datasource().loadAffirmations()
- Tạo biến có tên
recyclerView
và sử dụng phương thứcfindViewById()
để tìm tham chiếu đếnRecyclerView
trong bố cục.
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
- Để yêu cầu
recyclerView
sử dụng lớpItemAdapter
đã tạo, hãy tạo một thực thể mới củaItemAdapter
.ItemAdapter
yêu cầu hai tham số: ngữ cảnh (this
) của hoạt động này và lời tự động viên trongmyDataset
. - Gán đối tượng
ItemAdapter
cho thuộc tínhadapter
củarecyclerView
.
recyclerView.adapter = ItemAdapter(this, myDataset)
- Vì kích thước bố cục của
RecyclerView
là cố định trong bố cục hoạt động, bạn có thể đặt tham sốsetHasFixedSize
củaRecyclerView
thànhtrue
. Tuỳ chọn thiết lập này chỉ cần thiết khi muốn cải thiện hiệu quả hoạt động. Hãy sử dụng tuỳ chọn này nếu bạn biết rằng việc thay đổi nội dung sẽ không ảnh hưởng đến kích thước bố cục củaRecyclerView
.
recyclerView.setHasFixedSize(true)
- Khi hoàn thành, mã cho
MainActivity
sẽ tương tự như sau.
MainActivity.kt
package com.example.affirmations
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.adapter.ItemAdapter
import com.example.affirmations.data.Datasource
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Initialize data.
val myDataset = Datasource().loadAffirmations()
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter = ItemAdapter(this, myDataset)
// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true)
}
}
- Chạy ứng dụng. Bạn sẽ thấy danh sách các lời tự động viên hiển thị trên màn hình.
Xin chúc mừng! Bạn vừa tạo ứng dụng hiển thị danh sách dữ liệu với RecyclerView
và một trình chuyển đổi tuỳ chỉnh. Hãy dành thời gian để xem mã bạn đã tạo và hiểu được cách thức các thành phần tương tác với nhau như thế nào.
Ứng dụng này có tất cả phần bắt buộc để hiển thị lời tự động viên của bạn nhưng vẫn chưa sẵn sàng để phát hành chính thức. Vẫn còn một số điểm cần cải thiện đối với giao diện người dùng. Trong lớp học lập trình tiếp theo, bạn sẽ nâng cấp mã của mình, tìm hiểu cách thêm hình ảnh vào ứng dụng và trau chuốt thêm cho phần giao diện người dùng.
5. Mã giải pháp
Mã giải pháp cho lớp học lập trình này nằm trong dự án và mô-đun được hiển thị bên dưới. Lưu ý rằng một số tệp Kotlin nằm trong các gói khác nhau và được chỉ rõ trong lệnh package
ở đầu tệp.
res/values/strings.xml
<resources>
<string name="app_name">Affirmations</string>
<string name="affirmation1">I am strong.</string>
<string name="affirmation2">I believe in myself.</string>
<string name="affirmation3">Each day is a new opportunity to grow and be a better version of myself.</string>
<string name="affirmation4">Every challenge in my life is an opportunity to learn from.</string>
<string name="affirmation5">I have so much to be grateful for.</string>
<string name="affirmation6">Good things are always coming into my life.</string>
<string name="affirmation7">New opportunities await me at every turn.</string>
<string name="affirmation8">I have the courage to follow my heart.</string>
<string name="affirmation9">Things will unfold at precisely the right time.</string>
<string name="affirmation10">I will be present in all the moments that this day brings.</string>
</resources>
affirmations/data/Datasource.kt
package com.example.affirmations.data
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
class Datasource {
fun loadAffirmations(): List<Affirmation> {
return listOf<Affirmation>(
Affirmation(R.string.affirmation1),
Affirmation(R.string.affirmation2),
Affirmation(R.string.affirmation3),
Affirmation(R.string.affirmation4),
Affirmation(R.string.affirmation5),
Affirmation(R.string.affirmation6),
Affirmation(R.string.affirmation7),
Affirmation(R.string.affirmation8),
Affirmation(R.string.affirmation9),
Affirmation(R.string.affirmation10)
)
}
}
affirmations/model/Affirmation.kt
package com.example.affirmations.model
data class Affirmation(val stringResourceId: Int)
affirmations/MainActivty.kt
package com.example.affirmations
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.adapter.ItemAdapter
import com.example.affirmations.data.Datasource
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Initialize data.
val myDataset = Datasource().loadAffirmations()
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.adapter = ItemAdapter(this, myDataset)
// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true)
}
}
affirmations/adapter/ItemAdapter.kt
package com.example.affirmations.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
/**
* Adapter for the [RecyclerView] in [MainActivity]. Displays [Affirmation] data object.
*/
class ItemAdapter(
private val context: Context,
private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder.
// Each data item is just an Affirmation object.
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.item_title)
}
/**
* Create new views (invoked by the layout manager)
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
// create a new view
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return ItemViewHolder(adapterLayout)
}
/**
* Replace the contents of a view (invoked by the layout manager)
*/
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
/**
* Return the size of your dataset (invoked by the layout manager)
*/
override fun getItemCount() = dataset.size
}
src/main/res/layout/activty_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager" />
</FrameLayout>
src/main/res/layout/list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
6. Tóm tắt
- Tiện ích
RecyclerView
giúp bạn hiển thị danh sách dữ liệu. RecyclerView
sử dụng một mẫu của trình chuyển đổi để điều chỉnh và hiển thị dữ liệu.ViewHolder
tạo và lưu giữ các thành phần hiển thị choRecyclerView
.RecyclerView
đi kèm vớiLayoutManagers
được tích hợp sẵn.RecyclerView
uỷ quyền cách bố trí các phần tử choLayoutManagers
.
Để triển khai trình chuyển đổi, bạn hãy thực hiện các bước sau:
- Tạo một lớp mới cho trình chuyển đổi, ví dụ:
ItemAdapter
. - Tạo một lớp
ViewHolder
tuỳ chỉnh đại diện cho một thành phần hiển thị phần tử trong danh sách. Mở rộng lớp này từ lớpRecyclerView.ViewHolder
. - Chỉnh sửa lớp
ItemAdapter
để mở rộng lớp này từ lớpRecyclerView
Adapter
với lớpViewHolder
tuỳ chỉnh. - Triển khai các phương thức này trong trình chuyển đổi:
getItemsCount()
,onCreateViewHolder()
vàonBindViewHolder()
.