Skip to content

Instantly share code, notes, and snippets.

@tonyjs
Created April 2, 2017 11:06
Show Gist options
  • Save tonyjs/80b82ad61dc8bdcea28563f3191eb00a to your computer and use it in GitHub Desktop.
Save tonyjs/80b82ad61dc8bdcea28563f3191eb00a to your computer and use it in GitHub Desktop.
MultiViewTypeAdapter
package com.tonyjs.sample.multiviewtypeadapter.kotlin
import kotlinx.android.synthetic.main.item_a.view.*
/**
* Created by tonyjs on 2017. 4. 2..
*/
class ExampleAdapter : MultiViewTypeAdapter() {
companion object {
const val VIEW_TYPE_DIVIDER = 0
const val VIEW_TYPE_A = 1
const val VIEW_TYPE_B = 2
const val VIEW_TYPE_C = 3
}
override fun registerBinders() {
register<String>(VIEW_TYPE_A, R.layout.item_a, { holder, item ->
holder.itemView.tvTitle.text = item
})
register<String>(VIEW_TYPE_B, R.layout.item_b, { holder, item ->
holder.itemView.tvTitle.text = item
})
register<String>(VIEW_TYPE_C, R.layout.item_c, { holder, item ->
holder.itemView.tvTitle.text = item
})
register<Float>(VIEW_TYPE_DIVIDER, R.layout.item_divider, { _, _ ->
})
}
override fun getViewType(position: Int): Int {
if (items[position] is Float) {
return VIEW_TYPE_DIVIDER
}
return when (position % 3) {
1 -> VIEW_TYPE_B
2 -> VIEW_TYPE_C
else -> VIEW_TYPE_A
}
}
}
package com.tonyjs.sample.multiviewtypeadapter.kotlin
import android.support.annotation.LayoutRes
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* Created by tonyjs on 2017. 4. 2..
*/
abstract class MultiViewTypeAdapter : RecyclerView.Adapter<MultiViewTypeAdapter.ViewHolder>() {
open val items = mutableListOf<Any>()
val binderMap = hashMapOf<Int, Binder>()
fun <ITEM> register(viewType: Int, @LayoutRes layoutRes: Int,
binder: (holder: ViewHolder, ITEM) -> Unit) {
binderMap.put(viewType, object : Binder {
override val layoutResId: Int
get() = layoutRes
@Suppress("UNCHECKED_CAST")
override fun <T> bind(holder: ViewHolder, item: T) {
binder(holder, item as ITEM)
}
})
}
abstract fun registerBinders()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val resId = binderMap[viewType]?.layoutResId ?:
throw NullPointerException("require layout resource id")
val itemView = LayoutInflater.from(parent.context).inflate(resId, parent, false)
return ViewHolder(itemView)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val viewType = getItemViewType(position)
binderMap[viewType]?.bind(holder, items[position])
}
override fun getItemViewType(position: Int): Int {
if (binderMap.isEmpty()) {
registerBinders()
}
return getViewType(position)
}
abstract fun getViewType(position: Int): Int
override fun getItemCount(): Int = items.size
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
interface Binder {
@get:LayoutRes
val layoutResId: Int
fun <T> bind(holder: ViewHolder, item: T)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment