Menggunakan RecyclerView untuk menampilkan daftar yang bisa di-scroll

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.

cf10a913f9db0ee4.png

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.

dcf4599789b9c2a1.png

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.

  1. Mulai project Kotlin baru di Android Studio menggunakan template Empty Activity.
  2. Masukkan Affirmations sebagai Name aplikasi, com.example.affirmation sebagai Package name, dan pilih API Level 19 sebagai SDK Minimum.
  3. 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

  1. Di jendela Project, buka app > res > values > strings.xml. Saat ini file tersebut memiliki satu resource yang merupakan nama aplikasi.
  2. Di strings.xml, tambahkan afirmasi berikut sebagai resource string individual. Beri nama affirmation1, 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?

  1. 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)).

809a0d77a0759dc5.png

  1. 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 (misalnya TextView), bukan nama lengkapnya (misalnya, android.widget.TextView). Misalnya, Anda telah menggunakan pernyataan import untuk class seperti sqrt (import kotlin.math.sqrt) dan View (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, seperti TextView.

Membuat paket

  1. Di Android Studio, di panel Project, klik kanan app > java > com.example.affirmations, lalu pilih New > Package.

39f35a81a574b7ee.png

  1. 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!
  2. 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.

3d392f8da53adc6f.png

  1. 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.

  1. Klik kanan paket com.example.affirmations.model dan pilih New > Kotlin File/Class.

d9b07905f456ab1.png

  1. Di pop-up, pilih Class dan masukkan Affirmation sebagai nama class. Tindakan ini akan membuat file baru bernama Affirmation.kt dalam paket model.
  2. Buat Affirmation class data dengan menambahkan kata kunci data 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.

  1. Tambahkan val parameter bilangan bulat stringResourceId ke konstruktor class Affirmation. 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.

  1. Di Android Studio, di jendela Project, klik kanan app > java > com.example.affirmations dan pilih New > Package.
  2. Masukkan data sebagai bagian terakhir dari nama paket.
  3. Klik kanan paket data dan pilih new Kotlin File/Class.
  4. Masukkan Datasource sebagai nama class.
  5. Di dalam class Datasource, buat fungsi yang disebut loadAffirmations().

Fungsi loadAffirmations() perlu menampilkan daftar Affirmations. Untuk melakukannya, Anda perlu membuat daftar dan mengisinya dengan instance Affirmation untuk setiap string resource.

  1. Deklarasikan List<Affirmation> sebagai jenis nilai yang ditampilkan loadAffirmations() metode.
  2. Di bagian isi loadAffirmations(), tambahkan pernyataan return.
  3. Setelah kata kunci return, panggil listOf<>() untuk membuat List.
  4. Di dalam <> kurung sudut, tentukan jenis item daftar sebagai Affirmation. Jika perlu, impor com.example.affirmations.model.Affirmation.
  5. Di dalam tanda kurung, buat Affirmation, dengan meneruskan R.string.affirmation1 sebagai ID resource seperti yang ditunjukkan di bawah ini.
Affirmation(R.string.affirmation1)
  1. 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.

  1. Di layouts/activity_main.xml, berikan id TextView yang dilengkapi dengan template Anda sebesar textview.
  2. Di MainActivity dalam metode onCreate() setelah kode yang ada, dapatkan referensi ke textview.
val textView: TextView = findViewById(R.id.textview)
  1. Kemudian, tambahkan kode untuk membuat dan menampilkan ukuran daftar afirmasi. Buat Datasource, panggil loadAffirmations(), dapatkan ukuran daftar yang ditampilkan, konversikan ke string, dan tetapkan sebagai text dari textView.
textView.text = Datasource().loadAffirmations().size.toString()
  1. Jalankan aplikasi Anda. Layar akan terlihat seperti di bawah ini.

b4005973d4a0efc8.png

  1. 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

4e9c18b463f00bf7.png

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.

  1. Buka activity_main.xml (app > res > layout > activity_main.xml)
  2. Jika Anda belum menggunakannya, alihkan ke Tampilan terpisah.

7e7c3e8429267dac.png

  1. 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.

9e6f235be5fa31a8.png

  1. Pada XML, ganti ConstraintLayout dengan FrameLayout. 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>
  1. Beralih ke tampilan Design.
  2. Di Palette, pilih Containers, dan temukan RecyclerView.
  3. Tarik RecyclerView ke tata letak.
  4. Jika muncul, baca pop-up Add Project Dependency dan klik OK. (Jika pop-up tidak muncul, Anda tidak perlu melakukan tindakan apa pun.)
  5. Tunggu Android Studio selesai dan RecyclerView muncul di tata letak.
  6. Jika perlu, ubah atribut layout_width dan layout_height dari RecyclerView menjadi match_parent sehingga RecyclerView dapat mengisi seluruh layar.
  7. Setel ID resource RecyclerView ke recycler_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.

  1. Beralih kembali ke tampilan Code. Pada kode XML, di dalam elemen RecyclerView, tambahkan LinearLayoutManager sebagai atribut pengelola tata letak RecyclerView, 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.

  1. Di dalam RecyclerView, tambahkan atribut android:scrollbars yang disetel ke vertical.
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>
  1. 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.

  1. Di res > layout, buat File kosong baru yang disebut list_item.xml.
  2. Buka list_item.xml di tampilan Code.
  3. Tambahkan TextView dengan id item_title.
  4. Tambahkan wrap_content untuk layout_width dan layout_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.

dbb34ca516c804c6.png

Membuat class ItemAdapter

  1. Di Android Studio pada panel Project, klik kanan app > java > com.example.affirmations, lalu pilih New > Package.
  2. Masukkan adapter sebagai bagian terakhir dari nama paket.
  3. Klik kanan paket adapter dan pilih New > Kotlin File/Class.
  4. Masukkan ItemAdapter sebagai nama class, selesai, dan file ItemAdapter.kt akan terbuka.

Anda perlu menambahkan parameter ke konstruktor ItemAdapter, sehingga Anda dapat meneruskan daftar afirmasi ke adaptor.

  1. Tambahkan parameter ke ItemAdapter konstruktor yang merupakan val yang disebut dataset jenis List<Affirmation>. Impor Affirmation, jika perlu.
  2. Karena dataset hanya akan digunakan dalam class ini, jadikan private.

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.

  1. Tambahkan parameter ke konstruktor ItemAdapter yang merupakan val yang disebut context dari jenis Context. 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.

  1. Di dalam class ItemAdapter, sebelum kurung kurawal tutup untuk ItemAdapter, buat class ItemViewHolder.
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 oleh ItemAdapter, membuatnya dalam ItemAdapter akan menampilkan hubungan ini. Ini tidak wajib, tetapi membantu developer lain memahami struktur program Anda.
  1. Tambahkan private val view dari jenis View sebagai parameter ke konstruktor class ItemViewHolder.
  2. Jadikan ItemViewHolder subclass dari RecyclerView. ViewHolder dan meneruskan parameter view ke dalam konstruktor superclass.
  3. Di dalam ItemViewHolder, tentukan val properti textView yang berjenis TextView. Tetapkan tampilan dengan ID item_title yang Anda tentukan di list_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

  1. Tambahkan kode untuk memperluas ItemAdapter dari class abstrak RecyclerView.Adapter. Tentukan ItemAdapter.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.

  1. Letakkan kursor di ItemAdapter dan tekan Command+I (Control+I di Windows). Ini menampilkan daftar metode yang perlu Anda terapkan: getItemCount(), onCreateViewHolder(), dan onBindViewHolder().

7a8a383a8633094b.png

  1. 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.

  1. 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 adalah RecyclerView.
  • Parameter viewType yang menjadi penting saat ada beberapa jenis tampilan item dalam RecyclerView yang sama. Jika Anda memiliki tata letak item daftar yang berbeda yang ditampilkan dalam RecyclerView, 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.
  1. Dalam metode onCreateViewHolder(), dapatkan instance LayoutInflater dari konteks yang disediakan (context dari parent). Inflater tata letak akan mengetahui cara meng-inflate tata letak XML menjadi hierarki objek tampilan.
val adapterLayout = LayoutInflater.from(parent.context)
  1. 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 XML R.layout.list_item dan kelompok tampilan parent. Argumen boolean ketiga adalah attachToRoot. Argumen ini harus false, karena RecyclerView 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).

  1. Dalam onCreateViewHolder(), tampilkan instance ItemViewHolder baru yang tampilan root-nya adalah adapterLayout.
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.

  1. Di dalam onBindViewHolder(), buat val item dan dapatkan item pada position yang ditentukan dalam dataset.
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.

  1. Dengan instance objek Affirmation, Anda dapat menemukan ID resource string yang sesuai dengan memanggil item.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.

  1. Buka MainActivity.kt
  2. Di MainActivity,, buka metode onCreate(). Masukkan kode baru yang dijelaskan dalam langkah-langkah berikut setelah panggilan ke setContentView(R.layout.activity_main).
  3. Buat instance Datasource, dan panggil metode loadAffirmations() di dalamnya. Simpan daftar afirmasi yang ditampilkan dalam val yang bernama myDataset.
val myDataset = Datasource().loadAffirmations()
  1. Buat variabel yang disebut recyclerView dan gunakan findViewById() untuk menemukan referensi ke RecyclerView dalam tata letak.
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
  1. Untuk memberi tahu recyclerView agar menggunakan class ItemAdapter yang Anda buat, buat instance ItemAdapter baru. ItemAdapter mengharapkan dua parameter: konteks (this) dari aktivitas ini, dan afirmasi di myDataset.
  2. Tetapkan objek ItemAdapter ke properti adapter dari recyclerView.
recyclerView.adapter = ItemAdapter(this, myDataset)
  1. Karena ukuran tata letak RecyclerView tetap dalam tata letak aktivitas, Anda dapat menyetel parameter setHasFixedSize dari RecyclerView ke true. Setelan ini hanya diperlukan untuk meningkatkan performa. Gunakan setelan ini jika Anda mengetahui bahwa perubahan dalam isi tidak mengubah ukuran tata letak RecyclerView.
recyclerView.setHasFixedSize(true)
  1. 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)
    }
}
  1. Jalankan aplikasi Anda. Anda akan melihat daftar string afirmasi yang ditampilkan di layar.

427c10d4f29d769d.png

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 untuk RecyclerView.
  • RecyclerView hadir dengan LayoutManagers bawaan. RecyclerView mendelegasikan cara item ditata untuk LayoutManagers.

Untuk menerapkan adaptor:

  • Buat class baru untuk adaptor, misalnya, ItemAdapter.
  • Buat class ViewHolder kustom yang mewakili tampilan item daftar tunggal. Perluas dari class RecyclerView.ViewHolder.
  • Ubah class ItemAdapter untuk memperluas dari RecyclerView.Class Adapter dengan class ViewHolder kustom.
  • Implementasikan metode ini dalam adaptor: getItemsCount(), onCreateViewHolder(), dan onBindViewHolder().