Jika Anda memikirkan aplikasi yang biasa Anda gunakan di ponsel, hampir setiap aplikasi memiliki setidaknya satu daftar. Layar histori panggilan, aplikasi kontak, dan aplikasi media sosial favorit Anda menampilkan daftar data. Seperti yang ditunjukkan pada screenshot di bawah, beberapa aplikasi ini menampilkan daftar kata atau frasa sederhana, tempat aplikasi lain menampilkan item yang lebih kompleks seperti kartu yang menyertakan teks dan gambar. Apa pun kontennya, menampilkan daftar data adalah salah satu tugas UI yang paling umum di Android.
Untuk membantu Anda membuat aplikasi dengan daftar, Android menyediakan RecyclerView
. RecyclerView
dirancang agar sangat efisien, bahkan dengan daftar besar, dengan menggunakan kembali, atau mendaur ulang, tampilan yang telah di-scroll dari layar. Saat item daftar di-scroll dari layar, RecyclerView
menggunakan kembali tampilan tersebut untuk item daftar berikutnya yang akan ditampilkan. Itu artinya, item diisi dengan konten baru yang di-scroll ke layar. Perilaku RecyclerView
ini menghemat waktu pemrosesan dan membantu daftar ter-scroll dengan lebih lancar.
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
.
Dalam codelab ini, Anda akan membuat aplikasi Affirmations. Affirmations adalah aplikasi sederhana yang menampilkan sepuluh afirmasi positif sebagai teks dalam daftar scroll. Kemudian, dalam codelab lanjutan, Anda akan melangkah lebih jauh, menambahkan gambar yang menginspirasi untuk setiap afirmasi, dan menyempurnakan UI aplikasi.
Prasyarat
- Buat project dari template di Android Studio.
- Tambahkan resource string ke aplikasi.
- Tentukan tata letak di XML.
- Memahami class dan warisan di Kotlin (termasuk class abstrak).
- Mewarisi dari class yang ada dan mengganti metodenya.
- Gunakan dokumentasi di developer.android.com untuk class yang disediakan oleh framework Android.
Yang akan Anda pelajari
- Cara menggunakan
RecyclerView
untuk menampilkan daftar data. - Cara menyusun kode ke dalam paket
- Cara menggunakan adaptor dengan
RecyclerView
untuk menyesuaikan tampilan masing-masing item daftar.
Yang akan Anda buat
- Aplikasi yang menampilkan daftar string afirmasi menggunakan
RecyclerView
.
Yang Anda perlukan
- Komputer yang dilengkapi Android Studio versi 4.1 atau yang lebih baru.
Membuat project Empty Activity
Sebelum membuat project baru, pastikan Anda menggunakan Android Studio 4.1 atau yang lebih baru.
- Mulai project Kotlin baru di Android Studio menggunakan template Empty Activity.
- Masukkan Affirmations sebagai Name aplikasi, com.example.affirmation sebagai Package name, dan pilih API Level 19 sebagai SDK Minimum.
- Klik Finish untuk membuat project.
Langkah selanjutnya dalam membuat aplikasi Affirmations adalah menambahkan resource. Anda akan menambahkan hal berikut ke project.
- Resource string untuk ditampilkan sebagai afirmasi dalam aplikasi.
- Sumber data untuk memberikan daftar afirmasi ke aplikasi Anda.
Menambahkan string Afirmasi
- Di jendela Project, buka app > res > values > strings.xml. Saat ini file tersebut memiliki satu resource yang merupakan nama aplikasi.
- Di
strings.xml
, tambahkan afirmasi berikut sebagai resource string individual. Beri namaaffirmation1
,affirmation2
, dan seterusnya.
Teks afirmasi
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.
File strings.xml
akan terlihat seperti ini setelah Anda selesai.
<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>
Setelah menambahkan resource string, Anda dapat mereferensikannya dalam kode sebagai R.string.affirmation1
atau R.string.affirmation2
.
Membuat paket baru
Mengatur kode secara logis akan membantu Anda dan developer lain memahami, mempertahankan, dan memperluasnya. Dengan cara yang sama seperti mengatur dokumen ke dalam file dan folder, Anda dapat mengatur kode ke dalam file dan paket.
Apa yang dimaksud dengan paket?
- Di Android Studio, di jendela Project (Android), lihat file project baru di bagian app > java untuk aplikasi Affirmations. File tersebut akan terlihat mirip dengan screenshot di bawah ini, yang menunjukkan tiga paket, satu untuk kode Anda (com.example.affirmations), dan dua untuk file pengujian (com.example.affirmations (androidTest) dan com.example.affirmations (test)).
- Perhatikan bahwa nama paket terdiri dari beberapa kata yang dipisahkan oleh titik.
Ada dua cara untuk menggunakan paket.
- Buat paket yang berbeda untuk bagian kode yang berbeda. Misalnya, developer akan sering memisahkan class yang berfungsi dengan data dan class yang membuat UI menjadi paket yang berbeda.
- Gunakan kode dari paket lain dalam kode Anda. Untuk menggunakan class dari paket lain, Anda perlu mendefinisikannya dalam dependensi sistem build.
import
juga merupakan praktik standar dalam kode Anda sehingga Anda dapat menggunakan nama singkatnya (misalnyaTextView
), bukan nama lengkapnya (misalnya,android.widget.TextView
). Misalnya, Anda telah menggunakan pernyataanimport
untuk class sepertisqrt
(import kotlin.math.sqrt
) danView
(import android.view.View
).
Di aplikasi Affirmations, selain mengimpor class Android dan Kotlin, Anda juga akan mengatur aplikasi ke dalam beberapa paket. Meskipun Anda tidak memiliki banyak class untuk aplikasi, sebaiknya gunakan paket untuk mengelompokkan class berdasarkan fungsi.
Menamai paket
Nama paket dapat berupa apa saja, asalkan unik secara global; tidak ada paket lain yang dipublikasikan di mana pun yang dapat memiliki nama yang sama. Karena jumlah paket yang sangat besar, dan membuat nama unik yang acak itu sulit, pemrogram menggunakan konvensi untuk memudahkan dalam membuat dan memahami nama paket.
- Nama paket biasanya terstruktur dari umum ke khusus, dengan setiap bagian nama dalam huruf kecil dan dipisahkan oleh titik. Penting: Titik hanya sebagian dari nama. Titik ini tidak menunjukkan hierarki dalam kode atau meminta struktur folder!
- Karena domain internet bersifat unik secara global, ada konvensi untuk menggunakan domain, biasanya domain Anda atau domain bisnis Anda, sebagai bagian pertama dari nama.
- Anda dapat memilih nama paket untuk menunjukkan apa yang ada di dalam paket, dan bagaimana paket terkait satu sama lain.
- Untuk contoh kode seperti ini,
com.example
diikuti dengan nama aplikasi yang umum digunakan.
Berikut adalah beberapa contoh nama paket yang telah ditentukan sebelumnya beserta isinya:
kotlin.math
- Fungsi dan konstanta matematika.android.widget
- Tampilan, sepertiTextView
.
Membuat paket
- Di Android Studio, di panel Project, klik kanan app > java > com.example.affirmations, lalu pilih New > Package.
- Di pop-up New Package, perhatikan awalan nama paket yang disarankan. Bagian pertama nama paket yang disarankan adalah nama paket yang diklik kanan. Meskipun nama paket tidak membuat hierarki paket, penggunaan kembali bagian nama digunakan untuk menunjukkan hubungan dan pengaturan konten!
- Di pop-up, tambahkan model di akhir nama paket yang disarankan. Developer sering menggunakan model sebagai nama paket untuk class yang memodelkan (atau merepresentasikan) data.
- Tekan Enter. Ini akan membuat paket baru pada paket com.example.affirmations (root). Paket baru ini akan berisi class terkait data yang ditentukan di aplikasi Anda.
Membuat class data Affirmations
Dalam tugas ini, Anda akan membuat class yang disebut Affirmation.
Sebuah instance objek Affirmation
mewakili satu afirmasi dan berisi ID resource string dengan afirmasi.
- Klik kanan paket com.example.affirmations.model dan pilih New > Kotlin File/Class.
- Di pop-up, pilih Class dan masukkan
Affirmation
sebagai nama class. Tindakan ini akan membuat file baru bernamaAffirmation.kt
dalam paketmodel
. - Buat
Affirmation
class data dengan menambahkan kata kuncidata
sebelum definisi class. Hal ini akan menimbulkan error, karena class data harus memiliki setidaknya satu properti yang ditentukan.
Affirmation.kt
package com.example.affirmations.model
data class Affirmation {
}
Saat membuat instance Affirmation
, Anda harus meneruskan ID resource untuk string afirmasi. ID resource adalah bilangan bulat.
- Tambahkan
val
parameter bilangan bulatstringResourceId
ke konstruktor classAffirmation
. Tindakan ini akan menghapus error.
package com.example.affirmations.model
data class Affirmation(val stringResourceId: Int)
Membuat class untuk menjadi sumber data
Data yang ditampilkan di aplikasi Anda mungkin berasal dari sumber yang berbeda (misalnya dalam project aplikasi Anda atau dari sumber eksternal yang memerlukan sambungan ke internet untuk mendownload data). Hasilnya, data mungkin tidak dalam format yang sama persis dengan yang Anda butuhkan. Bagian lain aplikasi tidak perlu mempersoalkan asal data dari atau asal format data. Anda dapat dan sebaiknya menyembunyikan persiapan data ini di class Datasource
terpisah yang menyiapkan data untuk aplikasi.
Karena menyiapkan data adalah masalah terpisah, tempatkan class Datasource
di paket data terpisah.
- Di Android Studio, di jendela Project, klik kanan app > java > com.example.affirmations dan pilih New > Package.
- Masukkan
data
sebagai bagian terakhir dari nama paket. - Klik kanan paket
data
dan pilih new Kotlin File/Class. - Masukkan
Datasource
sebagai nama class. - Di dalam class
Datasource
, buat fungsi yang disebutloadAffirmations()
.
Fungsi loadAffirmations()
perlu menampilkan daftar Affirmations
. Untuk melakukannya, Anda perlu membuat daftar dan mengisinya dengan instance Affirmation
untuk setiap string resource.
- Deklarasikan
List<Affirmation>
sebagai jenis nilai yang ditampilkanloadAffirmations()
metode. - Di bagian isi
loadAffirmations()
, tambahkan pernyataanreturn
. - Setelah kata kunci
return
, panggillistOf<>()
untuk membuatList
. - Di dalam
<>
kurung sudut, tentukan jenis item daftar sebagaiAffirmation
. Jika perlu, imporcom.example.affirmations.model.Affirmation
. - Di dalam tanda kurung, buat
Affirmation
, dengan meneruskanR.string.affirmation1
sebagai ID resource seperti yang ditunjukkan di bawah ini.
Affirmation(R.string.affirmation1)
- Tambahkan
Affirmation
objek yang tersisa ke daftar semua afirmasi, yang dipisahkan dengan koma. Kode yang sudah selesai akan terlihat seperti berikut.
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)
)
}
}
[Opsional] Tampilkan ukuran daftar Affirmations di TextView
Untuk memverifikasi bahwa Anda dapat membuat daftar afirmasi, Anda dapat memanggil loadAffirmations()
dan menampilkan ukuran daftar afirmasi yang ditampilkan di TextView
yang disertakan dengan template aplikasi Empty Activity.
- Di
layouts/activity_main.xml
, berikanid
TextView
yang dilengkapi dengan template Anda sebesartextview
. - Di
MainActivity
dalam metodeonCreate()
setelah kode yang ada, dapatkan referensi ketextview
.
val textView: TextView = findViewById(R.id.textview)
- Kemudian, tambahkan kode untuk membuat dan menampilkan ukuran daftar afirmasi. Buat
Datasource
, panggilloadAffirmations()
, dapatkan ukuran daftar yang ditampilkan, konversikan ke string, dan tetapkan sebagaitext
daritextView
.
textView.text = Datasource().loadAffirmations().size.toString()
- Jalankan aplikasi Anda. Layar akan terlihat seperti di bawah ini.
- Hapus kode yang baru saja ditambahkan di
MainActivity
.
Dalam tugas ini, Anda akan menyiapkan RecyclerView
untuk menampilkan daftar Affirmations
.
Ada sejumlah bagian yang diperlukan dalam pembuatan dan penggunaan RecyclerView
. Anda dapat menganggapnya sebagai divisi dari tenaga kerja. Diagram di bawah menunjukkan ringkasan, dan Anda akan mempelajari lebih lanjut setiap bagian saat menerapkannya.
- item - Satu item data dari daftar yang akan ditampilkan. Mewakili satu objek
Affirmation
di aplikasi Anda. - Adapter - Mengambil data dan menyiapkannya agar
RecyclerView
ditampilkan. - ViewHolders - Kumpulan tampilan untuk
RecyclerView
yang akan digunakan dan digunakan kembali untuk menampilkan afirmasi. - RecyclerView - Tampilan di layar
Menambahkan RecyclerView ke tata letak
Aplikasi Affirmations terdiri dari satu aktivitas bernama MainActivity
, dan file tata letaknya disebut activity_main
.xml
. Pertama, Anda perlu menambahkan RecyclerView
ke tata letak MainActivity
.
- Buka
activity_main.xml
(app > res > layout > activity_main.xml) - Jika Anda belum menggunakannya, alihkan ke Tampilan terpisah.
- Hapus
TextView
.
Tata letak saat ini menggunakan ConstraintLayout
. ConstraintLayout
ideal dan fleksibel jika Anda ingin memosisikan beberapa tampilan turunan dalam tata letak. Karena tata letak Anda hanya memiliki satu tampilan turunan, RecyclerView
, Anda dapat beralih ke ViewGroup
sederhana yang disebut FrameLayout
yang harus digunakan untuk menyimpan satu tampilan turunan.
- Pada XML, ganti
ConstraintLayout
denganFrameLayout
. Tata letak yang telah selesai akan terlihat seperti yang ditunjukkan di bawah ini.
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>
- Beralih ke tampilan Design.
- Di Palette, pilih Containers, dan temukan RecyclerView.
- Tarik RecyclerView ke tata letak.
- Jika muncul, baca pop-up Add Project Dependency dan klik OK. (Jika pop-up tidak muncul, Anda tidak perlu melakukan tindakan apa pun.)
- Tunggu Android Studio selesai dan
RecyclerView
muncul di tata letak. - Jika perlu, ubah atribut
layout_width
danlayout_height
dariRecyclerView
menjadimatch_parent
sehinggaRecyclerView
dapat mengisi seluruh layar. - Setel ID resource
RecyclerView
kerecycler_view
.
RecyclerView
mendukung menampilkan item dengan cara yang berbeda, seperti daftar linear atau petak. Mengatur item akan ditangani oleh LayoutManager
. Framework Android menyediakan pengelola tata letak untuk tata letak item dasar. Aplikasi Affirmations menampilkan item sebagai daftar vertikal, sehingga Anda dapat menggunakan LinearLayoutManager
.
- Beralih kembali ke tampilan Code. Pada kode XML, di dalam elemen
RecyclerView
, tambahkanLinearLayoutManager
sebagai atribut pengelola tata letakRecyclerView
, seperti yang ditunjukkan di bawah ini.
app:layoutManager="LinearLayoutManager"
Agar dapat scroll daftar item yang lebih panjang dari layar secara vertikal, Anda perlu menambahkan scrollbar vertikal.
- Di dalam
RecyclerView
, tambahkan atributandroid:scrollbars
yang disetel kevertical
.
android:scrollbars="vertical"
Tata letak XML final harus terlihat seperti berikut:
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>
- Jalankan aplikasi Anda.
Project harus dikompilasi dan dijalankan tanpa masalah. Namun, hanya latar belakang putih yang ditampilkan di aplikasi Anda karena kehilangan kode penting. Saat ini, Anda memiliki source data dan RecyclerView
ditambahkan ke tata letak, tetapi RecyclerView
tidak memiliki informasi tentang cara menampilkan objek Affirmation
.
Mengimplementasikan Adapter untuk RecyclerView
Aplikasi Anda memerlukan cara untuk mengambil data dari Datasource
, dan memformatnya agar setiap Affirmation
dapat ditampilkan sebagai item di RecyclerView
.
Adapter adalah pola desain yang menyesuaikan data menjadi sesuatu yang dapat digunakan oleh RecyclerView
. Dalam hal ini, Anda memerlukan adaptor yang mengambil instance Affirmation
dari daftar yang ditampilkan oleh loadAffirmations()
, dan mengubahnya menjadi tampilan item daftar, sehingga dapat ditampilkan dalam RecyclerView.
Saat Anda menjalankan aplikasi, RecyclerView
menggunakan adaptor untuk mencari tahu cara menampilkan data Anda di layar. RecyclerView
meminta adaptor untuk membuat tampilan item daftar baru untuk item data pertama di daftar Anda. Setelah memiliki tampilan, kode tersebut akan meminta adaptor untuk menyediakan data untuk menggambar item. Proses ini berulang sampai RecyclerView
tidak memerlukan tampilan lain untuk mengisi layar. Jika hanya 3 tampilan item daftar yang cocok di layar sekaligus, RecyclerView
hanya akan meminta adaptor untuk menyiapkan 3 tampilan item daftar tersebut (bukan keseluruhan 10 tampilan item daftar).
Pada langkah ini, Anda akan membuat adaptor yang akan mengadaptasi instance objek Affirmation
sehingga dapat ditampilkan di RecyclerView
.
Membuat Adaptor
Adaptor memiliki beberapa bagian, dan Anda akan menulis sedikit kode yang lebih kompleks dari yang Anda lakukan dalam kursus ini sejauh ini. Tidak masalah jika Anda tidak sepenuhnya memahami detail pada awalnya. Setelah Anda menyelesaikan seluruh aplikasi ini dengan RecyclerView
, Anda dapat lebih memahami bagaimana semua bagiannya dapat disatukan. Anda juga dapat menggunakan kembali kode ini sebagai dasar untuk aplikasi mendatang yang Anda buat dengan RecyclerView
.
Membuat tata letak untuk item
Setiap item di RecyclerView
memiliki tata letak sendiri, yang Anda tentukan dalam file tata letak terpisah. Karena hanya akan menampilkan string, Anda dapat menggunakan TextView
untuk tata letak item.
- Di res > layout, buat File kosong baru yang disebut
list_item.xml
. - Buka
list_item.xml
di tampilan Code. - Tambahkan
TextView
denganid
item_title
. - Tambahkan
wrap_content
untuklayout_width
danlayout_height
, seperti yang ditunjukkan pada kode di bawah ini.
Perhatikan bahwa Anda tidak memerlukan ViewGroup
di sekitar tata letak, karena tata letak item daftar ini nantinya akan meningkat dan ditambahkan sebagai turunan ke induk 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" />
Atau, Anda mungkin telah menggunakan File > New > Layout Resource File, dengan Nama filelist_item.xml
dan TextView
sebagai Elemen root. Lalu perbarui kode yang dihasilkan agar sesuai dengan kode di atas.
Membuat class ItemAdapter
- Di Android Studio pada panel Project, klik kanan app > java > com.example.affirmations, lalu pilih New > Package.
- Masukkan
adapter
sebagai bagian terakhir dari nama paket. - Klik kanan paket
adapter
dan pilih New > Kotlin File/Class. - Masukkan
ItemAdapter
sebagai nama class, selesai, dan fileItemAdapter.kt
akan terbuka.
Anda perlu menambahkan parameter ke konstruktor ItemAdapter
, sehingga Anda dapat meneruskan daftar afirmasi ke adaptor.
- Tambahkan parameter ke
ItemAdapter
konstruktor yang merupakanval
yang disebutdataset
jenisList<Affirmation>
. ImporAffirmation
, jika perlu. - Karena
dataset
hanya akan digunakan dalam class ini, jadikanprivate
.
ItemAdapter.kt
import com.example.affirmations.model.Affirmation
class ItemAdapter(private val dataset: List<Affirmation>) {
}
ItemAdapter
memerlukan informasi tentang cara menyelesaikan resource string. Informasi ini, dan informasi lainnya tentang aplikasi, disimpan dalam instance objek Context
yang dapat Anda teruskan ke instance ItemAdapter
.
- Tambahkan parameter ke konstruktor
ItemAdapter
yang merupakanval
yang disebutcontext
dari jenisContext
. Posisikan sebagai parameter pertama dalam konstruktor.
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {
}
Membuat ViewHolder
RecyclerView
tidak berinteraksi langsung dengan tampilan item, namun berkaitan dengan ViewHolders
. ViewHolder
mewakili tampilan item daftar tunggal di RecyclerView
, dan dapat digunakan kembali jika memungkinkan. Instance ViewHolder
menyimpan referensi ke setiap tampilan dalam tata letak item daftar (dengan nama "holder tampilan"). Hal ini mempermudah untuk memperbarui tampilan item daftar dengan data baru. Holder tampilan juga menambahkan informasi yang digunakan RecyclerView
untuk memindahkan tampilan di layar dengan efisien.
- Di dalam class
ItemAdapter
, sebelum kurung kurawal tutup untukItemAdapter
, buat classItemViewHolder
.
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {
class ItemViewHolder()
}
- Menentukan class di dalam class lain disebut membuat class bertingkat.
- Karena
ItemViewHolder
hanya digunakan olehItemAdapter
, membuatnya dalamItemAdapter
akan menampilkan hubungan ini. Ini tidak wajib, tetapi membantu developer lain memahami struktur program Anda.
- Tambahkan
private
val
view
dari jenisView
sebagai parameter ke konstruktor classItemViewHolder
. - Jadikan
ItemViewHolder
subclass dariRecyclerView
.ViewHolder
dan meneruskan parameterview
ke dalam konstruktor superclass. - Di dalam
ItemViewHolder
, tentukanval
propertitextView
yang berjenisTextView
. Tetapkan tampilan dengan IDitem_title
yang Anda tentukan dilist_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)
}
}
Mengganti metode adaptor
- Tambahkan kode untuk memperluas
ItemAdapter
dari class abstrakRecyclerView.Adapter
. TentukanItemAdapter.ItemViewHolder
sebagai jenis holder tampilan dalam tanda kurung sudut.
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)
}
}
Anda akan melihat error karena Anda perlu menerapkan beberapa metode abstrak dari RecyclerView.Adapter
.
- Letakkan kursor di
ItemAdapter
dan tekan Command+I (Control+I di Windows). Ini menampilkan daftar metode yang perlu Anda terapkan:getItemCount()
,onCreateViewHolder()
, danonBindViewHolder()
.
- Pilih ketiga fungsi menggunakan Shift+klik dan klik OK.
Tindakan ini akan membuat stub dengan parameter yang benar untuk ketiga metode seperti yang ditunjukkan di bawah.
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")
}
Anda tidak akan melihat error lagi. Berikutnya, Anda perlu mengimplementasikan metode tersebut agar melakukan hal yang benar untuk aplikasi Anda.
Mengimplementasikan getItemCount()
Metode getItemCount()
harus menampilkan ukuran set data Anda. Data aplikasi Anda berada di properti dataset
yang Anda berikan ke konstruktor ItemAdapter
, dan Anda bisa mendapatkan ukurannya dengan size
.
- Ganti
getItemCount()
dengan ini:
override fun getItemCount() = dataset.size
Ini adalah cara yang lebih ringkas untuk menulis ini:
override fun getItemCount(): Int {
return dataset.size
}
Mengimplementasikan onCreateViewHolder()
Metode onCreateViewHolder()
dipanggil oleh pengelola tata letak untuk membuat holder tampilan baru untuk RecyclerView
(saat tidak ada holder tampilan yang ada yang dapat digunakan kembali). Ingatlah bahwa holder tampilan mewakili satu tampilan item daftar.
Metode onCreateViewHolder()
mengambil dua parameter dan menampilkan ViewHolder
baru.
- Parameter
parent
, yang merupakan kelompok tampilan tempat dilampirkannya tampilan item daftar baru sebagai turunan. Induk adalahRecyclerView
. - Parameter
viewType
yang menjadi penting saat ada beberapa jenis tampilan item dalamRecyclerView
yang sama. Jika Anda memiliki tata letak item daftar yang berbeda yang ditampilkan dalamRecyclerView
, ada berbagai jenis tampilan item. Anda hanya dapat mendaur ulang tampilan dengan jenis tampilan item yang sama. Dalam kasus Anda, hanya ada satu tata letak item daftar dan satu jenis tampilan item, sehingga Anda tidak perlu khawatir tentang parameter ini.
- Dalam metode
onCreateViewHolder()
, dapatkan instanceLayoutInflater
dari konteks yang disediakan (context
dariparent
). Inflater tata letak akan mengetahui cara meng-inflate tata letak XML menjadi hierarki objek tampilan.
val adapterLayout = LayoutInflater.from(parent.context)
- Setelah Anda memiliki instance objek
LayoutInflater
, tambahkan periode diikuti dengan panggilan metode lain untuk meng-inflate tampilan item daftar yang sebenarnya. Teruskan ID resource tata letak XMLR.layout.list_item
dan kelompok tampilanparent
. Argumen boolean ketiga adalahattachToRoot
. Argumen ini harusfalse
, karenaRecyclerView
menambahkan item ini ke hierarki tampilan saat waktu tersebut.
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
Sekarang adapterLayout
memiliki referensi ke tampilan item daftar (yang nantinya dapat kita temukan
tampilan turunan seperti TextView
).
- Dalam
onCreateViewHolder()
, tampilkan instanceItemViewHolder
baru yang tampilan root-nya adalahadapterLayout
.
return ItemViewHolder(adapterLayout)
Berikut adalah kode untuk onCreateViewHolder()
sejauh ini.
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)
}
Mengimplementasikan onBindViewHolder()
Metode terakhir yang perlu Anda ganti adalah onBindViewHolder()
. Metode ini dipanggil oleh pengelola tata letak untuk mengganti isi tampilan item daftar.
Metode onBindViewHolder()
memiliki dua parameter, ItemViewHolder
yang sebelumnya dibuat oleh metode onCreateViewHolder()
, dan int
yang mewakili item saat ini position
dalam daftar. Dalam metode ini, Anda akan menemukan objek Affirmation
yang tepat dari set data berdasarkan posisi.
- Di dalam
onBindViewHolder()
, buatval
item
dan dapatkan item padaposition
yang ditentukan dalamdataset
.
val item = dataset[position]
Terakhir, Anda harus memperbarui semua tampilan yang dirujuk oleh holder tampilan agar mencerminkan data yang benar untuk item ini. Dalam hal ini, hanya ada satu tampilan: TextView
dalam ItemViewHolder
. Tetapkan teks TextView
untuk menampilkan string Affirmation
bagi item ini.
- Dengan instance objek
Affirmation
, Anda dapat menemukan ID resource string yang sesuai dengan memanggilitem.stringResourceId
. Namun, ini adalah bilangan bulat dan Anda perlu menemukan pemetaan ke nilai string yang sebenarnya.
Dalam framework Android, Anda dapat memanggil getString()
dengan ID resource string, dan akan menampilkan nilai string yang terkait dengannya. getString()
adalah metode di class Resources
, dan Anda dapat memperoleh instance class Resources
melalui context
.
Itu berarti Anda dapat memanggil context.resources.getString()
dan memasukkan ID resource string. String yang dihasilkan dapat disetel sebagai text
dari textView
dalam holder
ItemViewHolder
. Singkatnya, baris kode ini memperbarui holder tampilan untuk menampilkan string afirmasi.
holder.textView.text = context.resources.getString(item.stringResourceId)
Metode onBindViewHolder()
yang telah selesai akan terlihat seperti ini.
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = dataset[position]
holder.textView.text = context.resources.getString(item.stringResourceId)
}
Berikut adalah kode adaptor yang selesai.
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
}
Setelah mengimplementasikan ItemAdapter
, Anda perlu memberi tahu RecyclerView
untuk menggunakan adaptor ini.
Mengubah MainActivity untuk menggunakan RecyclerView
Untuk menyelesaikan, Anda perlu menggunakan class Datasource
dan ItemAdapter
untuk membuat dan menampilkan item di RecyclerView
. Anda melakukannya di MainActivity
.
- Buka
MainActivity.kt
- Di
MainActivity,
, buka metodeonCreate()
. Masukkan kode baru yang dijelaskan dalam langkah-langkah berikut setelah panggilan kesetContentView(R.layout.activity_main).
- Buat instance
Datasource
, dan panggil metodeloadAffirmations()
di dalamnya. Simpan daftar afirmasi yang ditampilkan dalamval
yang bernamamyDataset
.
val myDataset = Datasource().loadAffirmations()
- Buat variabel yang disebut
recyclerView
dan gunakanfindViewById()
untuk menemukan referensi keRecyclerView
dalam tata letak.
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
- Untuk memberi tahu
recyclerView
agar menggunakan classItemAdapter
yang Anda buat, buat instanceItemAdapter
baru.ItemAdapter
mengharapkan dua parameter: konteks (this
) dari aktivitas ini, dan afirmasi dimyDataset
. - Tetapkan objek
ItemAdapter
ke propertiadapter
darirecyclerView
.
recyclerView.adapter = ItemAdapter(this, myDataset)
- Karena ukuran tata letak
RecyclerView
tetap dalam tata letak aktivitas, Anda dapat menyetel parametersetHasFixedSize
dariRecyclerView
ketrue
. Setelan ini hanya diperlukan untuk meningkatkan performa. Gunakan setelan ini jika Anda mengetahui bahwa perubahan dalam isi tidak mengubah ukuran tata letakRecyclerView
.
recyclerView.setHasFixedSize(true)
- Setelah selesai, kode untuk
MainActivity
harus mirip dengan kode berikut.
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)
}
}
- Jalankan aplikasi Anda. Anda akan melihat daftar string afirmasi yang ditampilkan di layar.
Selamat! Anda baru saja membuat aplikasi yang menampilkan daftar data dengan RecyclerView
dan adaptor khusus. Luangkan waktu untuk memeriksa kode yang Anda buat, dan pahami bagaimana masing-masing bagian bekerja sama.
Aplikasi ini memiliki semua bagian yang diperlukan untuk menampilkan afirmasi Anda, tetapi belum cukup siap untuk produksi. UI dapat menggunakan beberapa peningkatan. Pada codelab berikutnya, Anda akan meningkatkan kode, mempelajari cara menambahkan gambar ke aplikasi, dan memoles UI.
Kode solusi untuk codelab ini berada dalam project dan modul yang ditampilkan di bawah ini. Perlu diperhatikan bahwa beberapa file Kotlin berada dalam paket yang berbeda, seperti yang ditunjukkan oleh pernyataan package
di awal file.
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" />
RecyclerView
widget membantu Anda menampilkan daftar data.RecyclerView
menggunakan pola adaptor untuk menyesuaikan dan menampilkan data.ViewHolder
membuat dan melakukan tampilan untukRecyclerView
.RecyclerView
hadir denganLayoutManagers
bawaan.RecyclerView
mendelegasikan cara item ditata untukLayoutManagers
.
Untuk menerapkan adaptor:
- Buat class baru untuk adaptor, misalnya,
ItemAdapter
. - Buat class
ViewHolder
kustom yang mewakili tampilan item daftar tunggal. Perluas dari classRecyclerView.ViewHolder
. - Ubah class
ItemAdapter
untuk memperluas dariRecyclerView
.ClassAdapter
dengan classViewHolder
kustom. - Implementasikan metode ini dalam adaptor:
getItemsCount()
,onCreateViewHolder()
, danonBindViewHolder()
.