Multiple Layout Recycler View Tanpa Pusing dengan Adapter Delegate

Djaka Pradana Jaya Priambudi
Ladang Developer
Published in
5 min readApr 2, 2020

Hello hello hellooo, ga nyangka udah beda decade nih sejak terakhir kali nulis di medium. Dekade baru, semangat baru. Jangan lupa follow Ladang Developer biar ga pernah kelewat artikel keren keren lainnya.

Let’s be honest, Multiple Layout in RecyclerView is — HELL

Bagi kalian yang sudah agak lama developing di dunia Android, pasti pernah nih nemuin case dimana kita nampilin data dengan layout yang berbeda di satu RecyclerView.

Chat — Facebook’s Messenger
Chat — Facebook Messenger

Contoh simplenya: chat.

Sebagai ilustrasi aja, jika kita perlu membuat fitur chat dengan desain seperti itu, kita perlu membuat RecyclerView memakai 2 layout:
- Layout untuk Sender
- Layout untuk Receiver

Di dalam adapter kita bakal memiliki 2 ViewHolder berbeda untuk masing masing layout dan membuat adapter kita menjadi bloated.

“Yah gitu doang juga, tinggal if else if else aja disitu”

Yee bambang, kalo masih sedikit emang belum berasa tapi semakin banyak layout yang ada disitu, semakin susah juga Adapter itu untuk di pelihara dan dia lama lama menjadi sekumpulan sphagetti code.

Okay now what? — Let’s See How Multiple Layout RecyclerView Works First

Youtube RecyclerView

Mari kita lihat app Youtube, disana RecyclerView bisa menampilkan beberapa layout contohnya seperti diatas.

Agar kita bisa menggunakan multiple layout, kita perlu override getItemViewType. Basically function itu berguna agar nanti kita bisa membedakan viewType milik ViewHolder dengan cara memberi int yang berfungsi seperti id.

Lalu di onCreateViewHolder kita buat object sesuai dari viewType tadi dan di onBindViewHolder kita lakukan suatu aksi berdasarkan viewType dari holder.ViewType.

In short, kita harus :

  1. Membedakan / memilih ViewHolder yang dibutuhkan data
  2. Membuat ViewHolder yang dibutuhkan
  3. Mengikat data ke ViewHolder yang dibutuhkan

Delegation Pattern to the Rescue!!

Delegate simplenya, menyerahkan tugas ke objek lain. Sekarang berdasarkan 3 hal tadi, kita perlu membuat interface. Ini seperti blueprint berupa perintah perintah yang perlu dilakukan.

Next kita perlu sebuah object yang bisa memilih AdapterDelegate yang sesuai dengan yang kita butuhkan lalu memanggil function dari AdapterDelegate yang sesuai. Jadi lahirlah AdapterDelegateManager

Waitt.. viewType (idnya) nanti gimana?

viewType itu cuma int biasa kan? Karena mager juga nulisin satu persatu, mendingan kita manfaatin index array sebagai viewType jadi kita gak perlu mikirin gituan lagi. Di dalam getItemViewType diatas akan menjalankan function isForViewType yang ada di interface AdapterDelegate.

Optional

Kamu juga bisa biknin adapter generic seperti GenericAdapter agar kamu ga perlu bikinin Recyclerview.Adapter lagi.

Duhh kok ribet ? — Ribet di awal, gampang di masa depan

Memang pertama setup itu terutama kalau kalian baru tau generic dan delegation memang bingungin, but hey it’s worth it.

Oh iya setupnya juga hanya perlu satu kali, nanti kedepannya tinggal reuse doang.

Jangan patah semangat dulu, ada kejutan nanti di akhir 😉.

Let’s see it in action

Let’s say kita butuh menampilkan 3 layout seperti diatas. (Sebenernya kalau pakai DataBinding bisa jadi lebih clean, but I think that’s for another topic)

Without Delegate

File FeedAdapter bengkak, if else dimana - mana dan pastinya melanggar SOLID principle. Let’s say kamu perlu nambahin layout baru lagi, maka kamu perlu:

  1. Membuat ViewType (id) baru
  2. Membuat ViewHolder
  3. Memastikan onCreateViewHolder mereturn ViewHolder yang dibutuhkan sesuai viewType (if viewType == blabla)
  4. Memastikan onBindViewHolder membind viewType yang benar (if viewType == blabla)
  5. Binding data dengan ViewHolder baru

Cara ini tidak scalable, karena semakin banyak layout yang dibutuhkan, semakin besar pula file FeedAdapter yang pastinya bikin sakit kepala kalau ada bug ato ada 2 orang ngerjain itu secara bersamaan.

With Delegate

Jika kamu menggunakan delegate, berarti kamu perlu membuat delegate untuk masing masing layout. Brarti bakal ada 3 AdapterDelegate:

Jika kamu pakai GenericAdapter diatas, kamu bahkan tidak perlu membuat FeedAdapter. Activity mu akan seperti ini:

Jika kamu tidak pakai GenericAdapter diatas maka FeedAdapter mu akan seperti ini, lalu tinggal pakai seperti memakai Adapter RecyclerView biasa

Maka hasilnya seperti ini:

Multiple Layout RecyclerView

Waiit gimana kalau datanya cuma ada 1 tipe doang?

Simply do your logic in isViewType. For example, chat yang simple biasanya hanya perlu membedakan id pengirim, apakah itu milik user ato bukan. Contoh bisa dilihat disini. Singkatnya:

ReceiverDelegate
SenderDelegate

Kamu bisa juga membaca artikel keren (inspirasi dari tulisan ini jga hehe) Adapter Delegate dari Hannes Dorfmann di blognya.

Surprise surprise 🎉. Dia juga udah bikin librarynya lhoo (AdapterDelegate) untuk mengatasi masalah-masalah seperti ini:

Well there you go, sekarang di project mu jika perlu bikin multiple layout gak perlu banyak if else if else cukup addDelegate.

Oh iya kamu juga bisa lihat source code lengkap demo tadi disini (termasuk chat)

Okay that’s it. Don’t for get to follow my medium, 👏👏 and give any feedback~

Thanks for reading and see you guys next time! 👋

--

--