Codelab ini adalah bagian dari kursus Dasar-Dasar Android Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan. Semua codelab kursus tercantum di halaman landing codelab Dasar-Dasar Android Kotlin.
Pengantar
Codelab ini mengajarkan cara menggunakan RecyclerView untuk menampilkan daftar item. Dengan melanjutkan aplikasi pelacak tidur dari rangkaian codelab sebelumnya, Anda akan mempelajari cara yang lebih baik dan lebih serbaguna untuk menampilkan data, menggunakan RecyclerView dengan arsitektur yang direkomendasikan.
Yang harus sudah Anda ketahui
Anda harus memahami:
- Membangun antarmuka pengguna (UI) dasar menggunakan aktivitas, fragmen, dan tampilan.
- Menavigasi antar-fragmen, dan menggunakan
safeArgsuntuk meneruskan data antar-fragmen. - Menggunakan model tampilan, factory model tampilan, transformasi, serta
LiveDatadan pengamatnya. - Membuat database
Room, membuat DAO, dan menentukan entity. - Menggunakan coroutine untuk tugas database dan tugas berjalan lama lainnya.
Yang akan Anda pelajari
- Cara menggunakan
RecyclerViewdenganAdapterdanViewHolderuntuk menampilkan daftar item.
Yang akan Anda lakukan
- Ubah aplikasi TrackMySleepQuality dari pelajaran sebelumnya untuk menggunakan
RecyclerViewguna menampilkan data kualitas tidur.
Dalam codelab ini, Anda akan membuat bagian RecyclerView dari aplikasi yang melacak kualitas tidur. Aplikasi ini menggunakan database Room untuk menyimpan data tidur dari waktu ke waktu.
Aplikasi pelacak tidur pemula memiliki dua layar, yang diwakili oleh fragmen, seperti yang ditunjukkan pada gambar di bawah.

Layar pertama, yang ditampilkan di sebelah kiri, memiliki tombol untuk memulai dan menghentikan pelacakan. Layar ini juga menampilkan semua data tidur pengguna. Tombol Hapus akan menghapus semua data yang telah dikumpulkan aplikasi untuk pengguna secara permanen. Layar kedua, yang ditampilkan di sebelah kanan, adalah untuk memilih rating kualitas tidur.
Aplikasi ini menggunakan arsitektur yang disederhanakan dengan pengontrol UI, ViewModel, dan LiveData. Aplikasi ini juga menggunakan database Room untuk membuat data tidur tetap ada.

Daftar malam tidur yang ditampilkan di layar pertama berfungsi, tetapi tidak menarik. Aplikasi menggunakan pemformat kompleks untuk membuat string teks untuk tampilan teks dan angka untuk kualitas. Selain itu, desain ini tidak dapat diskalakan. Setelah Anda memperbaiki semua masalah ini dalam codelab ini, aplikasi akhir akan memiliki fungsi yang sama, dan layar utamanya akan terlihat seperti ini:

Menampilkan daftar atau petak data adalah salah satu tugas UI yang paling umum di Android. Daftar bervariasi dari yang sederhana hingga sangat kompleks. Daftar tampilan teks dapat menampilkan data sederhana, seperti daftar belanja. Daftar yang kompleks, seperti daftar tujuan liburan yang diberi anotasi, dapat menampilkan banyak detail kepada pengguna di dalam petak yang dapat di-scroll dengan header.
Untuk mendukung semua kasus penggunaan ini, Android menyediakan widget RecyclerView.

Manfaat terbesar RecyclerView adalah sangat efisien untuk daftar besar:
- Secara default,
RecyclerViewhanya berfungsi untuk memproses atau menggambar item yang saat ini terlihat di layar. Misalnya, jika daftar Anda memiliki seribu elemen, tetapi hanya 10 elemen yang terlihat,RecyclerViewhanya cukup berfungsi untuk menggambar 10 item di layar. Saat pengguna men-scroll,RecyclerViewakan mencari tahu item baru apa yang seharusnya ada di layar dan cukup berfungsi untuk menampilkan item tersebut. - Saat item di-scroll keluar dari layar, tampilan item didaur ulang. Artinya, item diisi dengan konten baru yang di-scroll ke layar. Perilaku
RecyclerViewini menghemat banyak waktu pemrosesan dan membantu daftar ter-scroll dengan lancar. - Saat item berubah, alih-alih menggambar ulang seluruh daftar,
RecyclerViewdapat memperbarui satu item tersebut. Ini adalah peningkatan efisiensi yang sangat besar saat menampilkan daftar item yang kompleks.
Dalam urutan yang ditunjukkan di bawah, Anda dapat melihat satu tampilan telah diisi dengan data, ABC. Setelah itu, layar akan ter-scroll ke luar layar, RecyclerView menggunakan kembali tampilan untuk data baru, XYZ.
Pola adaptor
Jika Anda pernah bepergian antarnegara yang menggunakan soket listrik yang berbeda, Anda mungkin tahu cara mencolokkan perangkat ke stopkontak menggunakan adaptor. Adaptor memungkinkan Anda mengonversi satu jenis steker ke jenis steker lainnya, yang sebenarnya mengonversi satu antarmuka ke antarmuka lainnya.
Pola adaptor dalam rekayasa software membantu objek bekerja dengan API lain. RecyclerView menggunakan adaptor untuk mengubah data aplikasi menjadi sesuatu yang dapat ditampilkan oleh RecyclerView, tanpa mengubah cara aplikasi menyimpan dan memproses data. Untuk aplikasi pelacak tidur, Anda membuat adaptor yang mengadaptasi data dari database Room menjadi sesuatu yang dapat ditampilkan oleh RecyclerView, tanpa mengubah ViewModel.
Menerapkan RecyclerView

Untuk menampilkan data dalam RecyclerView, Anda memerlukan bagian berikut:
- Data yang akan ditampilkan.
- Instance
RecyclerViewyang ditentukan dalam file tata letak Anda, untuk bertindak sebagai penampung tampilan. - Tata letak untuk satu item data.
Jika semua item daftar terlihat sama, Anda dapat menggunakan tata letak yang sama untuk semuanya, tetapi hal itu tidak wajib. Tata letak item harus dibuat secara terpisah dari tata letak fragmen, sehingga satu tampilan item dalam satu waktu dapat dibuat dan diisi dengan data. - Pengelola tata letak.
Pengelola tata letak menangani organisasi (tata letak) komponen UI dalam tampilan. - Pemegang tampilan.
Pemegang tampilan memperluas classViewHolder. Objek ini berisi informasi tampilan untuk menampilkan satu item dari tata letak item. Holder tampilan juga menambahkan informasi yang digunakanRecyclerViewuntuk memindahkan tampilan di layar dengan efisien. - Adaptor.
Adaptor menghubungkan data Anda keRecyclerView. Adaptor ini mengadaptasi data sehingga dapat ditampilkan dalamViewHolder.RecyclerViewmenggunakan adaptor untuk mencari tahu cara menampilkan data di layar.
Dalam tugas ini, Anda akan menambahkan RecyclerView ke file tata letak dan menyiapkan Adapter untuk mengekspos data tidur ke RecyclerView.
Langkah 1: Tambahkan RecyclerView dengan LayoutManager
Pada langkah ini, Anda mengganti ScrollView dengan RecyclerView dalam file fragment_sleep_tracker.xml.
- Download aplikasi RecyclerViewFundamentals-Starter dari GitHub.
- Bangun dan jalankan aplikasi. Perhatikan cara data ditampilkan sebagai teks sederhana.
- Buka file tata letak
fragment_sleep_tracker.xmldi tab Design di Android Studio. - Di panel Component Tree, hapus
ScrollView. Tindakan ini juga akan menghapusTextViewyang ada di dalamScrollView. - Di panel Palette, scroll daftar jenis komponen di sebelah kiri untuk menemukan Containers, lalu pilih.
- Tarik
RecyclerViewdari panel Palette ke panel Component Tree. TempatkanRecyclerViewdi dalamConstraintLayout.

- Jika dialog terbuka dan menanyakan apakah Anda ingin menambahkan dependensi, klik OK agar Android Studio menambahkan dependensi
recyclerviewke file Gradle Anda. Mungkin perlu waktu beberapa detik, lalu aplikasi Anda akan disinkronkan.

- Buka file
build.gradlemodul, scroll ke bagian akhir, dan perhatikan dependensi baru, yang terlihat mirip dengan kode di bawah:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
- Beralih kembali ke
fragment_sleep_tracker.xml. - Di tab Teks, cari kode
RecyclerViewyang ditampilkan di bawah:
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />- Beri
RecyclerViewidsleep_list.
android:id="@+id/sleep_list"- Posisikan
RecyclerViewagar menempati bagian layar yang tersisa di dalamConstraintLayout. Untuk melakukannya, batasi bagian atasRecyclerViewke tombol Mulai, bagian bawah ke tombol Hapus, dan setiap sisi ke induk. Tetapkan lebar dan tinggi tata letak ke 0 dp di Editor Tata Letak atau di XML, menggunakan kode berikut:
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/clear_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stop_button"- Tambahkan pengelola tata letak ke XML
RecyclerView. SetiapRecyclerViewmemerlukan pengelola tata letak yang memberi tahu cara memosisikan item dalam daftar. Android menyediakanLinearLayoutManager, yang secara default menata item dalam daftar vertikal baris lebar penuh.
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"- Beralihlah ke tab Desain dan perhatikan bahwa batasan yang ditambahkan telah menyebabkan
RecyclerViewmeluas untuk mengisi ruang yang tersedia.

Langkah 2: Buat tata letak item daftar dan penampung tampilan teks
RecyclerView hanyalah sebuah penampung. Pada langkah ini, Anda akan membuat tata letak dan infrastruktur untuk item yang akan ditampilkan di dalam RecyclerView.
Untuk mendapatkan RecyclerView yang berfungsi secepat mungkin, pertama-tama Anda menggunakan item daftar sederhana yang hanya menampilkan kualitas tidur sebagai angka. Untuk melakukannya, Anda memerlukan pemegang tampilan, TextItemViewHolder. Anda juga memerlukan tampilan, TextView, untuk data. (Pada langkah selanjutnya, Anda akan mempelajari lebih lanjut tentang pemegang tampilan dan cara menata semua data tidur.)
- Buat file tata letak bernama
text_item_view.xml. Tidak masalah elemen root apa yang Anda gunakan, karena Anda akan mengganti kode template. - Di
text_item_view.xml, hapus semua kode yang diberikan. - Tambahkan
TextViewdengan padding16dpdi awal dan akhir, serta ukuran teks24sp. Biarkan lebar cocok dengan induk, dan tinggi menggabungkan konten. Karena tampilan ini ditampilkan di dalamRecyclerView, Anda tidak perlu menempatkan tampilan di dalamViewGroup.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:textSize="24sp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />- Buka
Util.kt. Scroll ke bagian akhir dan tambahkan definisi yang ditampilkan di bawah, yang akan membuat classTextItemViewHolder. Tempatkan kode di bagian bawah file, setelah kurung penutup terakhir. Kode masuk keUtil.ktkarena penampung tampilan ini bersifat sementara, dan Anda akan menggantinya nanti.
class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)- Jika Anda diminta, impor
android.widget.TextViewdanandroidx.recyclerview.widget.RecyclerView.
Langkah 3: Buat SleepNightAdapter
Tugas inti dalam menerapkan RecyclerView adalah membuat adaptor. Anda memiliki holder tampilan sederhana untuk tampilan item, dan tata letak untuk setiap item. Sekarang Anda dapat membuat adaptor. Adaptor membuat penampung tampilan dan mengisinya dengan data agar RecyclerView dapat ditampilkan.
- Pada paket
sleeptracker, buat class Kotlin baru bernamaSleepNightAdapter. - Buat class
SleepNightAdaptermemperluasRecyclerView.Adapter. Class ini disebutSleepNightAdapterkarena mengadaptasi objekSleepNightmenjadi sesuatu yang dapat digunakan olehRecyclerView. Adaptor perlu mengetahui penampung tampilan yang akan digunakan, jadi teruskanTextItemViewHolder. Impor komponen yang diperlukan saat diminta, lalu Anda akan melihat error, karena ada metode wajib yang harus diterapkan.
class SleepNightAdapter: RecyclerView.Adapter<TextItemViewHolder>() {}- Di tingkat teratas
SleepNightAdapter, buat variabellistOfSleepNightuntuk menyimpan data.
var data = listOf<SleepNight>()- Di
SleepNightAdapter, gantigetItemCount()untuk menampilkan ukuran daftar malam tidur didata.RecyclerViewperlu mengetahui jumlah item yang dimiliki adaptor untuk ditampilkan, dan hal itu dilakukan dengan memanggilgetItemCount().
override fun getItemCount() = data.size- Di
SleepNightAdapter, ganti fungsionBindViewHolder(), seperti yang ditunjukkan di bawah.
FungsionBindViewHolder()dipanggil olehRecyclerViewuntuk menampilkan data satu item daftar pada posisi yang ditentukan. Jadi, metodeonBindViewHolder()menggunakan dua argumen: penampung tampilan, dan posisi data yang akan diikat. Untuk aplikasi ini, penampungnya adalahTextItemViewHolder, dan posisinya adalah posisi dalam daftar.
override fun onBindViewHolder(holder: TextItemViewHolder, position: Int) {
}- Di dalam
onBindViewHolder(), buat variabel untuk satu item pada posisi tertentu dalam data.
val item = data[position]ViewHolderyang Anda buat memiliki properti bernamatextView. Di dalamonBindViewHolder(), seteltextdaritextViewke angka kualitas tidur. Kode ini hanya menampilkan daftar angka, tetapi contoh sederhana ini memungkinkan Anda melihat cara adaptor memasukkan data ke dalam holder tampilan dan ke layar.
holder.textView.text = item.sleepQuality.toString()- Di
SleepNightAdapter, ganti dan terapkanonCreateViewHolder(), yang dipanggil saatRecyclerViewmemerlukan holder tampilan untuk merepresentasikan item.
Fungsi ini menggunakan dua parameter dan menampilkanViewHolder. Parameterparent, yang merupakan grup tampilan yang menyimpan pemegang tampilan, selalu berupaRecyclerView. ParameterviewTypedigunakan jika ada beberapa tampilan dalamRecyclerViewyang sama. Misalnya, jika Anda menempatkan daftar tampilan teks, gambar, dan video dalamRecyclerViewyang sama, fungsionCreateViewHolder()perlu mengetahui jenis tampilan yang akan digunakan.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextItemViewHolder {
}- Di
onCreateViewHolder(), buat instanceLayoutInflater.
Inflater tata letak mengetahui cara membuat tampilan dari tata letak XML.contextberisi informasi tentang cara meningkatkan penayangan dengan benar. Di adaptor untuk tampilan recycler, Anda selalu meneruskan konteks grup tampilanparent, yaituRecyclerView.
val layoutInflater = LayoutInflater.from(parent.context)- Di
onCreateViewHolder(), buatviewdengan memintalayoutinflateruntuk meng-inflate-nya.
Teruskan tata letak XML untuk tampilan, dan kelompok tampilanparentuntuk tampilan. Argumen ketiga, boolean, adalahattachToRoot. Argumen ini harusfalse, karenaRecyclerViewmenambahkan item ini ke hierarki tampilan saat waktunya.
val view = layoutInflater
.inflate(R.layout.text_item_view, parent, false) as TextView- Di
onCreateViewHolder(), tampilkanTextItemViewHolderyang dibuat denganview.
return TextItemViewHolder(view)- Adaptor harus memberi tahu
RecyclerViewsaatdataberubah, karenaRecyclerViewtidak mengetahui apa pun tentang data. Hanya mengetahui pemegang tampilan yang diberikan adaptor.
Untuk memberi tahuRecyclerViewsaat data yang ditampilkan telah berubah, tambahkan setter kustom ke variabeldatayang ada di bagian atas classSleepNightAdapter. Di setter, berikan nilai baru untukdata, lalu panggilnotifyDataSetChanged()untuk memicu penggambaran ulang daftar dengan data baru.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}Langkah 4: Beri tahu RecyclerView tentang Adapter
RecyclerView perlu mengetahui adaptor yang akan digunakan untuk mendapatkan penampung tampilan.
- Buka
SleepTrackerFragment.kt. - Di
onCreateview(), buat adaptor. Tempatkan kode ini setelah pembuatan modelViewModel, dan sebelum pernyataanreturn.
val adapter = SleepNightAdapter()- Kaitkan
adapterdenganRecyclerView.
binding.sleepList.adapter = adapter- Bersihkan dan bangun ulang project Anda untuk memperbarui objek
binding.
Jika Anda masih melihat error terkaitbinding.sleepListataubinding.FragmentSleepTrackerBinding, batalkan validasi cache dan mulai ulang. (Pilih File > Invalidate Caches / Restart.)
Jika Anda menjalankan aplikasi sekarang, tidak ada error, tetapi Anda tidak akan melihat data apa pun ditampilkan saat mengetuk Start, lalu Stop.
Langkah 5: Dapatkan data ke dalam adaptor
Sejauh ini Anda memiliki adaptor, dan cara untuk mendapatkan data dari adaptor ke RecyclerView. Sekarang Anda perlu memasukkan data ke adaptor dari ViewModel.
- Buka
SleepTrackerViewModel. - Temukan variabel
nights, yang menyimpan semua malam tidur, yang merupakan data yang akan ditampilkan. Variabelnightsditetapkan dengan memanggilgetAllNights()di database. - Hapus
privatedarinights, karena Anda akan membuat observer yang perlu mengakses variabel ini. Deklarasi Anda akan terlihat seperti ini:
val nights = database.getAllNights()- Di paket
database, bukaSleepDatabaseDao. - Temukan fungsi
getAllNights(). Perhatikan bahwa fungsi ini menampilkan daftar nilaiSleepNightsebagaiLiveData. Artinya, variabelnightsberisiLiveDatayang terus diperbarui olehRoom, dan Anda dapat mengamatinightsuntuk mengetahui kapan variabel tersebut berubah. - Buka
SleepTrackerFragment. - Di
onCreateView(), di bawah pembuatanadapter, buat observer pada variabelnights.
Dengan menyediakanviewLifecycleOwnerfragmen sebagai pemilik siklus proses, Anda dapat memastikan pengamat ini hanya aktif saatRecyclerViewada di layar.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
})- Di dalam pengamat, setiap kali Anda mendapatkan nilai non-null (untuk
nights), tetapkan nilai kedataadaptor. Berikut adalah kode lengkap untuk pengamat dan menyetel data:
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.data = it
}
})- Bangun dan jalankan kode Anda.
Anda akan melihat angka kualitas tidur sebagai daftar, jika adaptor Anda berfungsi. Screenshot di sebelah kiri menampilkan -1 setelah Anda mengetuk Mulai. Screenshot di sebelah kanan menunjukkan angka kualitas tidur yang diperbarui setelah Anda mengetuk Berhenti dan memilih rating kualitas.

Langkah 6: Pelajari cara daur ulang penampung tampilan
RecyclerView mendaur ulang penampung tampilan, yang berarti bahwa penampung tampilan tersebut digunakan kembali. Saat tampilan di-scroll keluar dari layar, RecyclerView akan menggunakan kembali tampilan tersebut untuk tampilan yang akan di-scroll ke layar.
Karena penampung tampilan ini didaur ulang, pastikan onBindViewHolder() menetapkan atau mereset penyesuaian apa pun yang mungkin telah ditetapkan item sebelumnya pada penampung tampilan.
Misalnya, Anda dapat menyetel warna teks menjadi merah di penampung tampilan yang menyimpan rating kualitas yang kurang dari atau sama dengan 1 dan menunjukkan kualitas tidur yang buruk.
- Di class
SleepNightAdapter, tambahkan kode berikut di akhironBindViewHolder().
if (item.sleepQuality <= 1) {
holder.textView.setTextColor(Color.RED) // red
}- Jalankan aplikasi.
- Tambahkan beberapa data kualitas tidur rendah, dan angkanya berwarna merah.
- Tambahkan rating tinggi untuk kualitas tidur hingga Anda melihat angka tinggi berwarna merah di layar.
KarenaRecyclerViewmenggunakan kembali penampung tampilan, pada akhirnyaRecyclerViewakan menggunakan kembali salah satu penampung tampilan merah untuk rating kualitas tinggi. Rating tinggi ditampilkan secara keliru dengan warna merah.

- Untuk memperbaikinya, tambahkan pernyataan
elseuntuk menyetel warna menjadi hitam jika kualitasnya tidak kurang dari atau sama dengan satu.
Dengan kedua kondisi yang jelas, penampung tampilan akan menggunakan warna teks yang benar untuk setiap item.
if (item.sleepQuality <= 1) {
holder.textView.setTextColor(Color.RED) // red
} else {
// reset
holder.textView.setTextColor(Color.BLACK) // black
}- Jalankan aplikasi, dan angka harus selalu memiliki warna yang benar.
Selamat! Sekarang Anda memiliki RecyclerView dasar yang berfungsi penuh.
Dalam tugas ini, Anda akan mengganti penampung tampilan sederhana dengan penampung yang dapat menampilkan lebih banyak data untuk malam tidur.
ViewHolder sederhana yang Anda tambahkan ke Util.kt hanya menggabungkan TextView dalam TextItemViewHolder.
class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)Jadi, mengapa RecyclerView tidak langsung menggunakan TextView? Satu baris kode ini menyediakan banyak fungsi. ViewHolder menjelaskan tampilan item dan metadata tentang tempatnya dalam RecyclerView. RecyclerView mengandalkan fungsi ini untuk memosisikan tampilan dengan benar saat daftar di-scroll, dan untuk melakukan hal-hal menarik seperti menganimasikan tampilan saat item ditambahkan atau dihapus di Adapter.
Jika RecyclerView perlu mengakses tampilan yang disimpan di ViewHolder, RecyclerView dapat melakukannya menggunakan properti itemView penampung tampilan. RecyclerView menggunakan itemView saat mengikat item untuk ditampilkan di layar, saat menggambar dekorasi di sekitar tampilan seperti batas, dan untuk menerapkan aksesibilitas.
Langkah 1: Buat tata letak item
Pada langkah ini, Anda akan membuat file tata letak untuk satu item. Tata letak terdiri dari ConstraintLayout dengan ImageView untuk kualitas tidur, TextView untuk durasi tidur, dan TextView untuk kualitas sebagai teks. Karena Anda sudah pernah membuat tata letak sebelumnya, salin dan tempel kode XML yang disediakan.
- Buat file resource tata letak baru dan beri nama
list_item_sleep_night. - Ganti semua kode dalam file dengan kode di bawah. Kemudian, pahami tata letak yang baru saja Anda buat.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content">
<ImageView
android:id="@+id/quality_image"
android:layout_width="@dimen/icon_size"
android:layout_height="60dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@drawable/ic_sleep_5" />
<TextView
android:id="@+id/sleep_length"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/quality_image"
app:layout_constraintTop_toTopOf="@+id/quality_image"
tools:text="Wednesday" />
<TextView
android:id="@+id/quality_string"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/sleep_length"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/sleep_length"
app:layout_constraintTop_toBottomOf="@+id/sleep_length"
tools:text="Excellent!!!" />
</androidx.constraintlayout.widget.ConstraintLayout>- Beralih ke tab Design di Android Studio. Dalam tampilan desain, tata letak Anda akan terlihat seperti screenshot di sebelah kiri di bawah. Dalam tampilan cetak biru, tampilannya akan seperti screenshot di sebelah kanan.

Langkah 2: Buat ViewHolder
- Buka
SleepNightAdapter.kt. - Buat class di dalam
SleepNightAdapterbernamaViewHolderdan buat class tersebut memperluasRecyclerView.ViewHolder.
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){}- Dalam
ViewHolder, dapatkan referensi ke tampilan. Anda memerlukan referensi ke tampilan yang akan diperbarui olehViewHolderini. Setiap kali mengikatViewHolderini, Anda perlu mengakses gambar dan kedua tampilan teks. (Anda akan mengonversi kode ini untuk menggunakan binding data nanti.)
val sleepLength: TextView = itemView.findViewById(R.id.sleep_length)
val quality: TextView = itemView.findViewById(R.id.quality_string)
val qualityImage: ImageView = itemView.findViewById(R.id.quality_image)Langkah 3: Gunakan ViewHolder di SleepNightAdapter
- Dalam definisi
SleepNightAdapter, gunakanSleepNightAdapter.ViewHolderyang baru saja Anda buat, bukanTextItemViewHolder.
class SleepNightAdapter: RecyclerView.Adapter<SleepNightAdapter.ViewHolder>() {Perbarui onCreateViewHolder():
- Ubah tanda tangan
onCreateViewHolder()untuk menampilkanViewHolder. - Ubah inflator tata letak untuk menggunakan resource tata letak yang benar,
list_item_sleep_night. - Hapus transmisi ke
TextView. - Daripada menampilkan
TextItemViewHolder, tampilkanViewHolder.
Berikut adalah fungsionCreateViewHolder()yang telah diperbarui:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater =
LayoutInflater.from(parent.context)
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night,
parent, false)
return ViewHolder(view)
}Perbarui onBindViewHolder():
- Ubah tanda tangan
onBindViewHolder()sehingga parameterholderadalahViewHolder, bukanTextItemViewHolder. - Di dalam
onBindViewHolder(), hapus semua kode, kecuali definisiitem. - Tentukan
valresyang menyimpan referensi keresourcesuntuk tampilan ini.
val res = holder.itemView.context.resources- Setel teks tampilan teks
sleepLengthke durasi. Salin kode di bawah, yang memanggil fungsi pemformatan yang disediakan dengan kode awal.
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)- Hal ini akan menimbulkan error, karena
convertDurationToFormatted()harus ditentukan. BukaUtil.ktdan hapus komentar kode serta impor terkait untuknya. (Pilih Code > Comment with Line comments.) - Kembali di
onBindViewHolder(), gunakanconvertNumericQualityToString()untuk menetapkan kualitas.
holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)- Anda mungkin perlu mengimpor fungsi ini secara manual.
import com.example.android.trackmysleepquality.convertDurationToFormatted
import com.example.android.trackmysleepquality.convertNumericQualityToString- Tetapkan ikon yang benar untuk kualitas. Ikon
ic_sleep_activebaru disediakan untuk Anda dalam kode awal.
holder.qualityImage.setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})- Berikut adalah fungsi
onBindViewHolder()yang telah diupdate dan selesai, yang menetapkan semua data untukViewHolder:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = data[position]
val res = holder.itemView.context.resources
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)
holder.qualityImage.setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}- Jalankan aplikasi Anda. Layar Anda akan terlihat seperti screenshot di bawah, yang menampilkan ikon kualitas tidur, beserta teks untuk durasi tidur dan kualitas tidur.

RecyclerView Anda kini selesai. Anda telah mempelajari cara menerapkan Adapter dan ViewHolder, serta menggabungkannya untuk menampilkan daftar dengan Adapter RecyclerView.
Kode Anda sejauh ini menunjukkan proses pembuatan adaptor dan holder tampilan. Namun, Anda dapat meningkatkan kualitas kode ini. Kode untuk menampilkan dan kode untuk mengelola pemegang tampilan tercampur, dan onBindViewHolder() mengetahui detail tentang cara memperbarui ViewHolder.
Di aplikasi produksi, Anda mungkin memiliki beberapa pemegang tampilan, adaptor yang lebih kompleks, dan beberapa developer yang melakukan perubahan. Anda harus menyusun kode sehingga semua yang terkait dengan holder tampilan hanya ada di holder tampilan.
Langkah 1: Faktorkan ulang onBindViewHolder()
Pada langkah ini, Anda akan memfaktorkan ulang kode dan memindahkan semua fungsi penampung tampilan ke ViewHolder. Tujuan pemfaktoran ulang ini bukan untuk mengubah tampilan aplikasi bagi pengguna, tetapi untuk mempermudah dan membuat developer lebih aman saat mengerjakan kode. Untungnya, Android Studio memiliki alat untuk membantu.
- Di
SleepNightAdapter, dionBindViewHolder(), pilih semuanya kecuali pernyataan untuk mendeklarasikan variabelitem. - Klik kanan, lalu pilih Refactor > Extract > Function.
- Beri nama fungsi
binddan terima parameter yang disarankan. Klik Oke.
Fungsibind()ditempatkan di bawahonBindViewHolder().
private fun bind(holder: ViewHolder, item: SleepNight) {
val res = holder.itemView.context.resources
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
holder.quality.text = convertNumericQualityToString(item.sleepQuality, res)
holder.qualityImage.setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}- Tempatkan kursor pada kata
holderdari parameterholderbind(). TekanAlt+Enter(Option+Enterdi Mac) untuk membuka menu maksud. Pilih Convert parameter to receiver untuk mengonversinya menjadi fungsi ekstensi yang memiliki tanda tangan berikut:
private fun ViewHolder.bind(item: SleepNight) {...}- Potong dan tempel fungsi
bind()keViewHolder. - Menjadikan
bind()publik. - Impor
bind()ke adaptor, jika perlu. - Karena sekarang berada di
ViewHolder, Anda dapat menghapus bagianViewHolderdari tanda tangan. Berikut adalah kode akhir untuk fungsibind()di classViewHolder.
fun bind(item: SleepNight) {
val res = itemView.context.resources
sleepLength.text = convertDurationToFormatted(
item.startTimeMilli, item.endTimeMilli, res)
quality.text = convertNumericQualityToString(
item.sleepQuality, res)
qualityImage.setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}Langkah 2: Refaktorkan onCreateViewHolder
Metode onCreateViewHolder() di adaptor saat ini meng-inflate tampilan dari resource tata letak untuk ViewHolder. Namun, inflasi tidak ada hubungannya dengan adaptor, dan semuanya berkaitan dengan ViewHolder. Inflasi akan terjadi pada ViewHolder.
- Di
onCreateViewHolder(), pilih semua kode di isi fungsi. - Klik kanan, lalu pilih Refactor > Extract > Function.
- Beri nama fungsi
fromdan terima parameter yang disarankan. Klik Oke. - Letakkan kursor pada nama fungsi
from. TekanAlt+Enter(Option+Enterdi Mac) untuk membuka menu maksud. - Pilih Pindahkan ke objek pendamping. Fungsi
from()harus berada dalam objek pendamping sehingga dapat dipanggil di classViewHolder, bukan dipanggil di instanceViewHolder. - Pindahkan objek
companionke dalam classViewHolder. - Menjadikan
from()publik. - Di
onCreateViewHolder(), ubah pernyataanreturnuntuk menampilkan hasil pemanggilanfrom()di classViewHolder.
MetodeonCreateViewHolder()danfrom()yang telah selesai akan terlihat seperti kode di bawah, dan kode Anda harus di-build dan dijalankan tanpa error.
override fun onCreateViewHolder(parent: ViewGroup, viewType:
Int): ViewHolder {
return ViewHolder.from(parent)
}companion object {
fun from(parent: ViewGroup): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)
return ViewHolder(view)
}
}- Ubah tanda tangan class
ViewHoldersehingga konstruktornya bersifat pribadi. Karenafrom()sekarang menjadi metode yang menampilkan instanceViewHolderbaru, tidak ada alasan bagi siapa pun untuk memanggil konstruktorViewHolderlagi.
class ViewHolder private constructor(itemView: View) : RecyclerView.ViewHolder(itemView){- Jalankan aplikasi. Aplikasi Anda akan dibuat dan berjalan sama seperti sebelumnya, yang merupakan hasil yang diinginkan setelah memfaktorkan ulang.
Project Android Studio: RecyclerViewFundamentals
- Menampilkan daftar atau petak data adalah salah satu tugas UI yang paling umum di Android.
RecyclerViewdirancang agar efisien meskipun saat menampilkan daftar yang sangat besar. RecyclerViewhanya melakukan pekerjaan yang diperlukan untuk memproses atau menggambar item yang saat ini terlihat di layar.- Saat item di-scroll keluar dari layar, tampilannya akan didaur ulang. Artinya, item diisi dengan konten baru yang di-scroll ke layar.
- Pola adaptor dalam rekayasa software membantu objek bekerja sama dengan API lain.
RecyclerViewmenggunakan adaptor untuk mengubah data aplikasi menjadi sesuatu yang dapat ditampilkan, tanpa perlu mengubah cara aplikasi menyimpan dan memproses data.
Untuk menampilkan data dalam RecyclerView, Anda memerlukan bagian berikut:
- RecyclerView
Untuk membuat instanceRecyclerView, tentukan elemen<RecyclerView>dalam file tata letak. - LayoutManager
RecyclerViewmenggunakanLayoutManageruntuk mengatur tata letak item dalamRecyclerView, seperti menatanya dalam petak atau dalam daftar linear.
Di<RecyclerView>dalam file tata letak, tetapkan atributapp:layoutManagerke pengelola tata letak (sepertiLinearLayoutManageratauGridLayoutManager).
Anda juga dapat menetapkanLayoutManageruntukRecyclerViewsecara terprogram. (Teknik ini dibahas dalam codelab berikutnya.) - Tata letak untuk setiap item
Buat tata letak untuk satu item data dalam file tata letak XML. - Adapter
Buat adaptor yang menyiapkan data dan cara data akan ditampilkan diViewHolder. Kaitkan adaptor denganRecyclerView.
SaatRecyclerViewberjalan,RecyclerViewakan menggunakan adaptor untuk mencari tahu cara menampilkan data di layar.
Adaptor mengharuskan Anda menerapkan metode berikut:
–getItemCount()untuk menampilkan jumlah item.
–onCreateViewHolder()untuk menampilkanViewHolderuntuk item dalam daftar.
–onBindViewHolder()untuk menyesuaikan data dengan tampilan untuk item dalam daftar. - ViewHolder
ViewHolderberisi informasi tampilan untuk menampilkan satu item dari tata letak item. - Metode
onBindViewHolder()di adaptor menyesuaikan data dengan tampilan. Anda selalu mengganti metode ini. Biasanya,onBindViewHolder()meng-inflate tata letak untuk item, dan menempatkan data dalam tampilan di tata letak. - Karena
RecyclerViewtidak mengetahui apa pun tentang data,Adapterperlu memberi tahuRecyclerViewsaat data tersebut berubah. GunakannotifyDataSetChanged()untuk memberi tahuAdapterbahwa data telah berubah.
Kursus Udacity:
Dokumentasi developer Android:
Bagian ini mencantumkan kemungkinan tugas pekerjaan rumah untuk siswa yang mengerjakan codelab ini sebagai bagian dari kursus yang dipimpin oleh instruktur. Instruktur menentukan hal berikut:
- Memberikan pekerjaan rumah jika diperlukan.
- Memberi tahu siswa cara mengirimkan tugas pekerjaan rumah.
- Memberi nilai tugas pekerjaan rumah.
Instruktur bisa menggunakan saran ini sesuai kebutuhan, dan bebas menugaskan pekerjaan rumah lain yang dirasa cocok.
Jika Anda menyelesaikan codelab ini sendiri, gunakan tugas pekerjaan rumah ini untuk menguji pengetahuan Anda.
Jawab pertanyaan-pertanyaan berikut
Pertanyaan 1
Bagaimana cara RecyclerView menampilkan item? Pilih semua yang sesuai.
▢ Menampilkan item dalam daftar atau petak.
▢ Men-scroll secara vertikal atau horizontal.
▢ Men-scroll secara diagonal di perangkat yang lebih besar seperti tablet.
▢ Memungkinkan tata letak khusus saat daftar atau petak tidak cukup untuk kasus penggunaan.
Pertanyaan 2
Apa saja manfaat dari menggunakan RecyclerView? Pilih semua yang sesuai.
▢ Menampilkan daftar besar secara efisien.
▢ Otomatis memperbarui data.
▢ Meminimalkan kebutuhan pemuatan ulang saat item diperbarui, dihapus, atau ditambahkan ke daftar.
▢ Menggunakan kembali tampilan yang di-scroll keluar dari layar untuk menampilkan item berikutnya yang di-scroll ke layar.
Pertanyaan 3
Apa saja beberapa alasan penggunaan adaptor? Pilih semua yang sesuai.
▢ Pemisahan masalah memudahkan perubahan dan pengujian kode.
▢ RecyclerView tidak bergantung pada data yang ditampilkan.
▢ Lapisan pemrosesan data tidak perlu memikirkan bagaimana data akan ditampilkan.
▢ Aplikasi akan berjalan lebih cepat.
Pertanyaan 4
Manakah dari hal berikut yang benar tentang ViewHolder? Pilih semua yang sesuai.
▢ Tata letak ViewHolder ditentukan dalam file tata letak XML.
▢ Ada satu ViewHolder untuk setiap unit data dalam set data.
▢ Anda dapat memiliki lebih dari satu ViewHolder di RecyclerView.
▢ Adapter mengikat data ke ViewHolder.
Mulai pelajaran berikutnya: