Sebuah Panduan Menggunakan RecyclerView dan CardView dengan Kotlin

Bagus Aji Santoso

Diterjemahkan dari A Kotlin Android RecyclerView and CardView Tutorial

Di pembahasan bab ini, contoh project yang akan kita buat memanfaatkan komponen CardView dan RecyclerView untuk membuat sekumpulan card yang bisa di scroll. Aplikasi yang jadinya akan menampilkan sekumpulan card berisi gambar dan teks. Selain menampilkan sekumpulan card, aplikasi ini juga akan memiliki fitur untuk menampilkan suatu pesan saat salah satu card di klik. (Silahkan lihat gambar aplikasi jadi di akhir artikel).

Membuat Project CardDemo

Buat sebuah project baru di Android Studio, tuliskan CardDemo ke dalam kolom Application name dan ebookfrenzy.com sebagai Company Domain sebelum menekan tombol Next.

Di halaman form factor, aktifkan opsi untuk Phone and Tablet lalu atur minimum SDK ke API 14: Android 4.0 (IceCreamSandwich) dan lanjutkan ke halaman selanjutnya.

Di bab berikutnya kita akan membahas bagaimana mengaktifkan fitur scroll AppBar, Toolbar dan CoodinatorLayout yang juga dipakai di project ini. Pada halaman pemilihan activity awal, pilihlah Basic Activity dan beri nama CardDemoActivity dengan layout bernama activity_card_demo. Klik tombol Finish untuk memulai proses pembuatan project.

Setelah project selesai dibuat, buka file content_card_demo.xml di Layout Editor lalu pilih dan hapus objek TextView “Hello World”.

Hapus Floating Action Button

Saat memilih Basic Activity, layout akan memiliki sebuah floating action button yang tidak dibutuhkan project ini. Buka dulu activity_card_demo.xml lalu pilih floating action button dan tekan tombol delete di keyboard untuk menghapusnya. Edit file CardDemoActivity.kt lalu hapus blok kode untuk floating action button dari dalam method onCreate:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_card_demo)
setSupportActionBar(toolbar)

// yang ini
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}//sampai sini
}

Menambahkan Dependensi RecyclerView dan CardView

Dari dalam jendela Project tool, cari dan buka file bernama build.gradle (app) dan modifikasi bagian dependensi untuk menambahkan support library RecyclerView dan CardView:

Kiri dalam mode Android dan kanan dalam mode Project
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:cardview-v7:26.1.0'
.
.
}

Saat diminta, resync konfigurasi Gradle yang baru dengan mengklik tautan Sync Now di warning bar.

Mendesain Layout CardView

Layout untuk view yang berada di dalam card akan ditulis di file XML terpisah. Di panel Project, klik kanan app -> res -> layout entry dan pilih opsi New -> Layout resource file. Pada jendela New Resource Dialog yang muncul, tulisakan card_layout ke dalam File name dan android.support.v7.widget.CardView ke dalam root element sebelum memilih tombol OK.

Buka file card_layout.xml ke Layout Editor tool, pindah ke Text mode lalu modifikasi layout-nya sehingga menjadi sebagai berikut:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/card_view"
android:layout_margin="5dp"
card_view:cardBackgroundColor="#81C784"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="3dp"
card_view:contentPadding="4dp" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp" >

<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/item_image"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_title"
android:layout_toEndOf="@+id/item_image"
android:layout_toRightOf="@+id/item_image"
android:layout_alignParentTop="true"
android:textSize="30sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_detail"
android:layout_toEndOf="@+id/item_image"
android:layout_toRightOf="@+id/item_image"
android:layout_below="@+id/item_title" />

</RelativeLayout>
</android.support.v7.widget.CardView>

Menambahkan RecyclerView

Buka file layout activity_card_demo.xml dan modifikasi file tersebut untuk menambahkan komponen RecyclerView sebelum AppBarLayout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
android:fitsSystemWindows="true"
tools:contextcom.ebookfrenzy.carddemo.CardDemoActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
.
.
.

Membuat Adapter RecyclerView

Seperti yang telah di bahas di bab sebelumnya, RecyclerView memerlukan sebuah adapter untuk mengurusi pembuatan item-item di dalamnya. Buat kelas ini di dalam project dengan cara klik kanan di folder app -> java -> com.ebookfrenzy.carddemo di jendela Project lalu pilih New -> Kotlin File/Class. Pada dialog Create New Class, masukkan RecyclerAdapter ke dalam kolom Name: sebelum memilih tombol OK untuk membuat file Kotlin baru.

Edit file RecyclerAdapter.kt yang baru untuk menambahkan kode-kode yang diperlukan. Sekarang kelas RecyclerAdapter telah meng-extends kelas RecyclerView.Adapter sehingga bisa bekerja dengan komponen RecyclerView yang tadi sudah ditambahkan:

package com.ebookfrenzy.carddemo

import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView

class RecyclerAdapter : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
// daftar title yang akan ditampilkan di card
private val titles = arrayOf("Chapter One",
"Chapter Two", "Chapter Three", "Chapter Four",
"Chapter Five", "Chapter Six", "Chapter Seven",
"Chapter Eight")
// daftar teks yang akan ditampilkan juga
private val details = arrayOf("Item one details", "Item two details",
"Item three details", "Item four details",
"Item file details", "Item six details",
"Item seven details", "Item eight details")
// Daftar gambar yang sudah disimpan di folder drawable
private val images = intArrayOf(R.drawable.android_image_1,
R.drawable.android_image_2, R.drawable.android_image_3,
R.drawable.android_image_4, R.drawable.android_image_5,
R.drawable.android_image_6, R.drawable.android_image_7,
R.drawable.android_image_8)
}

Di dalam kelas RecyclerAdapter sekarang kita perlu membuat kelas ViewHolder yang mengarahkan elemen-elemen di file card_layout.xml. Lanjutkan penulisan file RecyclerAdapter.kt dengan kode-kode berikut:

.
.
class RecyclerAdapter : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
.
.
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

var itemImage: ImageView
var itemTitle: TextView
var itemDetail: TextView

init {
itemImage = itemView.findViewById(R.id.item_image)
itemTitle = itemView.findViewById(R.id.item_title)
itemDetail = itemView.findViewById(R.id.item_detail)
}
}
.
.
}

Kelas ViewHolder memiliki sebuah ImageView dan dua TextView bersama sebuah constructor yang melakukan findViewById ke dalam card_layout.xml.

Komponen berikutnya yang perlu ditambahkan ke dalam file RecyclerAdapter.kt adalah implementasi method onCreateViewHolder():

override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
val v = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.card_layout, viewGroup, false)
return ViewHolder(v)
}

Method ini akan dipanggil oleh RecyclerView untuk memuat objek ViewHolder sebelumnya. Ia menampilkan konten view file card_layout.xml serta membuat sebuah instance baru dari kelas ViewHolder sebelum mengirimkannya ke RecyclerView.

Tujuan method onBindViewHolder() ialah untuk mengisi konten card_layout.xml dengan data yang berbeda-beda. Ia akan menerima objek ViewHolder dan sebuah integer (angka) yang mewakili data ke berapa untuk ditampilkan. Angka ini dapat dipakai untuk mengambil isi array berdasarkan index. Penampilan data ke layout bisa dipakai memanfaatkan variabel-variabel yang sebelumnya sudah di tulis dan di findViewById-kan di dalam kelas ViewHolder:

override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.itemTitle.text = titles[i]
viewHolder.itemDetail.text = details[i]
viewHolder.itemImage.setImageResource(images[i])
}

Komponen terakhir yang diperlukan oleh kelas adapter adalah implementasi method getItem() yang hanya berfungsi untuk me-return jumlah data yang ada di dalam array titles:

override fun getItemCount(): Int {
return titles.size
}

Menambahkan File Gambar

Selain dua TextView, layout card juga memiliki sebuah ImageView yang mana sudah diatur oleh adapter RecyclerView. Sebelum aplikasi dicoba gambar-gambar ini perlu ditambahkan. Gambar-gambar yang akan di pakai memiliki struktur nama android_image_<n>.jpg dimana n adalah angka dan bisa disalin dari folder project_icons source code yang bisa diunduh di:

http://www.ebookfrenzy.com/web/as30kotlin/index.php

Cari file ini dengan Explorer/Finder kemudian salinlah delapan gambar ke dalam folder app -> res -> drawable:

Inisialisasi Komponen RecyclerView

Sampai tahap ini project telah memiliki komponen RecyclerView, sebuah layout XML untuk CardView dan sebuah adapter untuk RecyclerView. Langkah terakhir yang perlu kita lakukan sebelum mengujinya adalah melakukan inisialisasi RecyclerView dengan memberikan sebuah layout manager, membuat sebuah instance dari adapter dan mengarahkannya ke objek RecyclerView. Untuk contoh project ini, RecyclerView akan menggunakan LinearLayoutManager. Modifikasi file CardDemoActivity.kt lalu perbarui method onCreate() untuk melakukan inisialisasi:

package com.ebookfrenzy.carddemo

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem

import kotlinx.android.synthetic.main.activity_card_demo.*
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.LinearLayoutManager

class CardDemoActivity : AppCompatActivity() {

private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_card_demo)
setSupportActionBar(toolbar)

layoutManager = LinearLayoutManager(this)
recycler_view.layoutManager = layoutManager

adapter = RecyclerAdapter()
recycler_view.adapter = adapter

}
.
.
}

Menguji Aplikasi

Compile dan jalankan aplikasi di perangkat asli atau emulatorlalu coba untuk melakukan scroll agar terlihat item-item yang berbeda:

Merespon Sentuhan Card

Fase terakhir adalah memastikan bahwa card yang ada di dalam list dapat dipilih sehingga sebuah sentuhan pada sebuah card akan menampilkan pesan ke layar. Untuk merespon klik, kelas ViewHolder perlu untuk di modifikasi untuk memberikan sebuah onClickListener pada setiap item view. Edit file RecyclerAdapter.kt lalu modifikasi kelas ViewHolder sehingga menjadi:

.
.
import android.support.design.widget.Snackbar
.
.
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

var itemImage: ImageView
var itemTitle: TextView
var itemDetail: TextView

init {
itemImage = itemView.findViewById(R.id.item_image)
itemTitle = itemView.findViewById(R.id.item_title)
itemDetail = itemView.findViewById(R.id.item_detail)

itemView.setOnClickListener { v: View ->

}
}
}
.
.
}

Di dalam handler onClick, kita bisa menambahkan kode untuk menampilkan pesan saat salah satu card terpilih. Untuk mengetahui card keberapa yang disentuh kita bisa meminta bantuan method getAdapterPosition() bawaan kelas RecyclerView.ViewHolder. Tambahkan kode di dalam blok onClick sebelumnya menjadi:

itemView.setOnClickListener { v: View  ->
var position: Int = getAdapterPosition()

Snackbar.make(v, "Click detected on item $position",
Snackbar.LENGTH_LONG).setAction("Action", null).show()
}

Sekarang saatnya kita mengaktifkan ripple effect yang menjadi ciri khas material design yang muncul ketika item terpilih. Untuk mengaktifkannya kita cukup tambhakan beberapa atribut pada tag CardView di file card_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/card_view"
android:layout_margin="5dp"
card_view:cardBackgroundColor="#81C784"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="3dp"
card_view:contentPadding="4dp"
android:foreground="?selectableItemBackground"
android:clickable="true" >

Jalankan lagi aplikasinya lalu pastikan saat card disentuh akan muncul ripple effect disertai dengan Snackbar berisi pesan angka item terpilih.

Kesimpulan

Kita sudah membahas bagaimana mengombinasikan CardView dam RecyclerView untuk menampilkan card based item yang bisa di scroll. Project yang dicontohkan juga membahas bagaimana cara mendeteksi klik pada item termasuk mendidentifikasi index item terpilih serta mengaktifkan ripple effect yang mempercantik tampilan.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade