Skip to content

Instantly share code, notes, and snippets.

@vasyafromrussia
Last active January 26, 2019 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasyafromrussia/04968a5936d53b48d4cde688fa4d5b3e to your computer and use it in GitHub Desktop.
Save vasyafromrussia/04968a5936d53b48d4cde688fa4d5b3e to your computer and use it in GitHub Desktop.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val list = findViewById<RecyclerView>(R.id.list)
val adapter = MultiTypeAdapter()
list.layoutManager = LinearLayoutManager(this)
list.adapter = adapter
adapter.registerType(
String::class,
TypeHolder(
viewCreator = {
TextView(this).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
},
viewBinder = { view, item ->
view.text = item
},
onClickListener = { view, item ->
Toast.makeText(this, item, Toast.LENGTH_SHORT).show()
}
)
)
adapter.registerType(
Int::class,
TypeHolder(
viewCreator = {
EditText(this).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
},
viewBinder = { view, item ->
view.setText(item.toString())
},
onClickListener = { view, item ->
Toast.makeText(this, item.toString(), Toast.LENGTH_SHORT).show()
}
)
)
adapter.addItems(listOf("A", "B", 1, "C", "D", 2, "E", "F", 3, "G"))
}
}
class MultiTypeAdapter : RecyclerView.Adapter<ViewHolder>() {
private val viewCreators = mutableMapOf<Int, TypeHolder<Any, View>>()
private val types = mutableMapOf<KClass<*>, Int>()
private val items = mutableListOf<Any>()
fun addItems(items: List<Any>) {
this.items.addAll(items)
notifyDataSetChanged()
}
fun <T: Any, V : View> registerType(kClass: KClass<T>, typeHolder: TypeHolder<T, V>) {
val type = kClass.hashCode()
types[kClass] = type
viewCreators[type] = typeHolder as TypeHolder<Any, View>
}
override fun onCreateViewHolder(parent: ViewGroup, type: Int): ViewHolder {
val viewCreator = viewCreators[type]?.viewCreator ?: throw IllegalStateException("type not registered")
return ViewHolder(viewCreator)
}
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val type = getItemViewType(position)
val typeHolder = viewCreators[type] ?: throw IllegalStateException("type not registered")
val binder = typeHolder.viewBinder
val item = items[position]
binder(holder.itemView, item)
holder.itemView.setOnClickListener { typeHolder.onClickListener(it, item) }
}
override fun getItemViewType(position: Int): Int {
val item = items[position]
return types[item::class] ?: throw IllegalStateException()
}
}
class ViewHolder(viewCreator: () -> View) : RecyclerView.ViewHolder(viewCreator())
class TypeHolder<T, V : View>(
val viewCreator: () -> V,
val viewBinder: (V, T) -> Unit,
val onClickListener: (V, T) -> Unit
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment