Skip to content

Instantly share code, notes, and snippets.

@StratusHunter
Created February 21, 2018 11:11
Show Gist options
  • Save StratusHunter/2058ca9d3b1259c8ad4b6351c5e46b81 to your computer and use it in GitHub Desktop.
Save StratusHunter/2058ca9d3b1259c8ad4b6351c5e46b81 to your computer and use it in GitHub Desktop.
Attempting to remove some of the boilerplate from RecyclerView Adapters. Also off the back of this creating an adapter that accepts a header view similar to iOS tableHeaderView. By using getViewType(position:Int) you can provide different cell types to then create within onCreateItemViewHolder.
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
/**
* Created by Terence Baker on 08/02/2018.
*/
abstract class HeaderItemAdapter<H : RecyclerView.ViewHolder, I : RecyclerView.ViewHolder, T>(items: Array<T>, itemClickListener: OnRecyclerItemClickListener<T>? = null) : ItemAdapter<I, T>(items, itemClickListener) {
companion object {
private const val HEADER = -1
private const val CELL = 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
HEADER -> onCreateHeaderViewHolder(parent)
else -> onCreateItemViewHolder(parent, viewType)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (position == 0) {
@Suppress("UNCHECKED_CAST")
(holder as? H)?.let { onBindHeaderViewHolder(it) }
}
else {
super.onBindViewHolder(holder, position - 1)
}
}
override fun getItemViewType(position: Int): Int {
return when (position) {
0 -> HEADER
else -> getViewType(position - 1)
}
}
override fun getItemCount(): Int = items.count() + 1
abstract fun onCreateHeaderViewHolder(parent: ViewGroup): H
abstract fun onBindHeaderViewHolder(holder: H)
internal open fun getViewType(position: Int) = CELL
}
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
/**
* Created by Terence Baker on 08/02/2018.
*/
abstract class ItemAdapter<I : RecyclerView.ViewHolder, T>(items: Array<T>, private val itemClickListener: OnRecyclerItemClickListener<T>? = null) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
open var items: Array<T> = items
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return onCreateItemViewHolder(parent, viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.itemView.setOnClickListener { itemClickListener?.onItemClick(position, items[position]) }
@Suppress("UNCHECKED_CAST")
(holder as? I)?.let { onBindItemViewHolder(it, items[position]) }
}
abstract fun onCreateItemViewHolder(parent: ViewGroup, viewType: Int): I
abstract fun onBindItemViewHolder(holder: I, item: T)
override fun getItemCount(): Int = items.count()
}
/**
* Created by Terence Baker on 08/02/2018.
*/
interface OnRecyclerItemClickListener<in T> {
fun onItemClick(position: Int, item: T)
}
class MyAdapter(items: Array<MyObject> = arrayOf(), itemClickListener: OnRecyclerItemClickListener<MyObject> = null) : HeaderItemAdapter<MyHeaderViewHolder, MyViewHolder, MyObject>(items, itemClickListener) {
override fun onCreateHeaderViewHolder(parent: ViewGroup) = MyHeaderViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cell_my_header, parent, false))
override fun onCreateItemViewHolder(parent: ViewGroup, viewType: Int) = MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.cell_my, parent, false))
override fun onBindHeaderViewHolder(holder: MyHeaderViewHolder) {
holder.setup()
}
override fun onBindItemViewHolder(holder: MyViewHolder, item: MyObject) {
holder.setup(item)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment