Android RecyclerView With Different Layout / View Type (Kotlin)
July 23, 2018Declare classes for different layout / view type. I have two different layout classes: Image
and Property
, where both implement resource: Int
to store the layout id.
sealed class ViewItem(val resource: Int) {
class Image(val imageResource: String): ViewItem(R.layout.content_pin_list_item_image)
class Property(val icon: Int?,
val value: String,
val onClick: (() -> Unit)? = null,
val onInit: ((viewHolder: LocalListAdapter.ViewHolder) -> Unit)? = null): ViewItem(R.layout.content_pin_list_item)
}
NOTE: If you don’t like sealed
class, you could use abstract
or interface
.
Declare the adapter class.
getItemViewType
return layout id, which is used inonCreateViewHolder
to inflate layout byviewType
.- I use LayoutContainer Support to enable
Android Extensions plugin supports
forViewHolder
. You can access view by id usingholder.<VIEW_ID>
syntax.
class LocalListAdapter() : RecyclerView.Adapter<LocalListAdapter.ViewHolder>() {
private var items: List<ViewItem> = listOf()
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return items[position].resource
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(viewType, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
val context = holder.containerView.context
when (item) {
is ViewItem.Image -> {
holder.apply {
/*
Glide.with(itemView)
.load(item.imageResource)
.into(imageView)
imageView.setOnClickListener {
}
*/
}
}
is ViewItem.Property -> {
holder.apply {
/*
if (item.icon != null) {
iconImageView.setImageResource(item.icon)
}
else {
iconImageView.isVisible = false
}
textView.text = item.value
if (item.onClick != null) {
itemView.setOnClickListener {
item.onClick?.invoke()
}
}
else {
itemView.setOnClickListener(null)
itemView.setBackgroundColor(Color.TRANSPARENT)
}
item.onInit?.let { init ->
init.invoke(this)
}
*/
}
}
}
}
fun replaceItems(items: List<ViewItem>) {
this.items = items
notifyDataSetChanged()
}
inner class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer
}
I usually initialize the adapter with empty items.
adapter = LocalListAdapter()
recyclerView.adapter = adapter
When items are loaded from network or database, call replaceItems
.
val items = mutableListOf<ViewItem>()
// load image
items.add(ViewItem.Image("https://code.luasoftware.com/img/logo-badge.png"))
// load property - info
ViewItem.Property(R.drawable.ic_map_black_24dp, "My Address").also {
items.add(it)
}
// load property - info + click
ViewItem.Property(R.drawable.ic_access_time_black_24dp,
"Click Me",
onClick = {
// do something
}).also {
items.add(it)
}
adapter.replaceItems(items)
- algo-trading
- algolia
- analytics
- android
- android-ktx
- android-permission
- android-studio
- apps-script
- bash
- binance
- bootstrap
- bootstrapvue
- chartjs
- chrome
- cloud-functions
- coding-interview
- contentresolver
- coroutines
- crashlytics
- crypto
- css
- dagger2
- datastore
- datetime
- docker
- eslint
- firebase
- firebase-auth
- firebase-hosting
- firestore
- firestore-security-rules
- flask
- fontawesome
- fresco
- git
- github
- glide
- godot
- google-app-engine
- google-cloud-storage
- google-colab
- google-drive
- google-maps
- google-places
- google-play
- google-sheets
- gradle
- html
- hugo
- inkscape
- java
- java-time
- javascript
- jetpack-compose
- jetson-nano
- kotlin
- kotlin-serialization
- layout
- lets-encrypt
- lifecycle
- linux
- logging
- lubuntu
- markdown
- mate
- material-design
- matplotlib
- md5
- mongodb
- moshi
- mplfinance
- mysql
- navigation
- nginx
- nodejs
- npm
- nuxtjs
- nvm
- pandas
- payment
- pip
- pwa
- pyenv
- python
- recylerview
- regex
- room
- rxjava
- scoped-storage
- selenium
- social-media
- ssh
- ssl
- static-site-generator
- static-website-hosting
- sublime-text
- ubuntu
- unit-test
- uwsgi
- viewmodel
- viewpager2
- virtualbox
- vue-chartjs
- vue-cli
- vue-router
- vuejs
- vuelidate
- vuepress
- web-development
- web-hosting
- webpack
- windows
- workmanager
- wsl
- yarn