Laravel dan Android Tutorial

Blogger news

Android Heterogeneous RecyclerView

Tidak ada komentar
Ada saatnya item recyclerview pada Android menampilkan bermacam-macam  type layout tergantung tipe datanya seperti apa. istilahnya item layout pada recyclerview bisa bermacam-macam. misalnya seperti gambar berikut ini.


bisa dilihat diatas item pada recyclerview ada dua macam. satu dengan gambar dan yang satu cuma text saja. apakah item layoutnya satu jadi terus pakai if? tentu tidak, jawabannya adalah memakai dua view holder pada adapternya.

sebelumnya siapkan dulu project android baru dengan data binding (MVVM). langsung saja ke view modelnya disini untuk list datanya disini pakai dua model. ImageModel dan TextModel.

package com.yoesuv.myheterogeneous.viewmodels
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.yoesuv.myheterogeneous.models.ImageModel
import com.yoesuv.myheterogeneous.models.TextModel
class MainViewModel(application: Application) : AndroidViewModel(application) {
var listHeterogeneous: MutableLiveData<MutableList<Any>> = MutableLiveData()
private var listData: MutableList<Any> = arrayListOf()
fun setupData() {
listData.clear()
listData.add(ImageModel("Dian Sastro Wardoyo","https://www.unreservedmedia.com/wp-content/uploads/2018/11/dian-sastrowardoryo-ryan-tandya.jpg"))
listData.add(TextModel("Nicholas Saputra","Artis"))
listData.add(ImageModel("Chelsea Islan","https://1.bp.blogspot.com/-GMCBs0do1AA/WRaYJS_heyI/AAAAAAAAKbM/4i_XAQ-hjsMHxtLQvUNWNE0rzjQKN-iZwCEw/s1600/islan4.jpg"))
listData.add(ImageModel("IU","https://www.allkpop.com/upload/2018/10/af_org/27105129/IU.jpg"))
listData.add(TextModel("Leonel Messi","Atlet Sepakbola"))
listData.add(ImageModel("Pevita Pearce","https://1.bp.blogspot.com/-dtfgEusKDyg/V8VGxwdHx_I/AAAAAAAALUQ/DOd04r2NBj4kza6SslGpihanSqmnUUKNwCLcB/s1600/pevita%2Bpearce.jpg"))
listData.add(ImageModel("Isyana Sarasvati","https://img.jakpost.net/c/2017/10/05/2017_10_05_33640_1507175962._large.jpg"))
listData.add(TextModel("Didi Kempot","Penyanyi Legend"))
listHeterogeneous.postValue(listData)
}
}
variable live data listHeterogeneous akan di observe di activity.
setelah model dan viewmodel siap silahkan buat dua layout untuk item image dan item text
seperti gambar diatas layout yang satu ada gambarnya dan yang satu cuma text saja.

sekarang bagian terpenting pada Adapternya. mulai dari bagian atas dahulu buat constant untuk masing-masing tipe item dan juga diff callback untuk masing-masing model. untuk menentukan typenya override getItemViewType. selanjutnya tinggal di if di onCreateViewHolder berdasarkan view holder masing-masing (disini pakai dua view holder)

package com.yoesuv.myheterogeneous.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.yoesuv.myheterogeneous.R
import com.yoesuv.myheterogeneous.databinding.ItemImageBinding
import com.yoesuv.myheterogeneous.databinding.ItemTextBinding
import com.yoesuv.myheterogeneous.models.ImageModel
import com.yoesuv.myheterogeneous.models.TextModel
import com.yoesuv.myheterogeneous.viewmodels.ItemImageViewModel
import com.yoesuv.myheterogeneous.viewmodels.ItemTextViewModel
class MyListAdapter: ListAdapter<Any, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
companion object {
const val ITEM_IMAGE = 0
const val ITEM_TEXT = 1
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Any>() {
override fun areContentsTheSame(oldItem: Any, newItem: Any): Boolean {
if (oldItem is ImageModel && newItem is ImageModel) {
return oldItem.name == newItem.name
} else if (oldItem is TextModel && newItem is TextModel) {
return oldItem.fullName == newItem.fullName
} else {
return true
}
}
override fun areItemsTheSame(oldItem: Any, newItem: Any): Boolean {
return oldItem == newItem
}
}
}
override fun getItemViewType(position: Int): Int {
return if (getItem(position) is ImageModel) {
ITEM_IMAGE
} else {
ITEM_TEXT
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == ITEM_IMAGE) {
val binding: ItemImageBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_image, parent, false)
return ItemImageViewHolder(binding)
} else {
val binding: ItemTextBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_text, parent, false)
return ItemTextViewHolder(binding)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ItemImageViewHolder) {
val imageModel = getItem(holder.adapterPosition) as ImageModel
holder.bindData(imageModel)
} else if (holder is ItemTextViewHolder) {
val textModel = getItem(holder.adapterPosition) as TextModel
holder.bindData(textModel)
}
}
class ItemImageViewHolder(private val binding: ItemImageBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindData(imageModel: ImageModel) {
binding.itemImage = ItemImageViewModel(imageModel)
binding.executePendingBindings()
}
}
class ItemTextViewHolder(private val binding: ItemTextBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindData(textModel: TextModel) {
binding.itemText = ItemTextViewModel(textModel)
binding.executePendingBindings()
}
}
}
jadi intinya adalah memakai dua viewholder pada adapter jika ingin menampilkan item yang berbeda-beda. atau nantinya bisa dikembangkan lebih dari dua view holder.

check repository githubnya disini.
selamat mencoba.

Tidak ada komentar :

Posting Komentar