Skip to content

Instantly share code, notes, and snippets.

@swarawan
Last active January 1, 2021 09:52
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 swarawan/6f80ae90751a000633f855dc1369e88a to your computer and use it in GitHub Desktop.
Save swarawan/6f80ae90751a000633f855dc1369e88a to your computer and use it in GitHub Desktop.
General Recycler View Adapter
class DiffCallback : DiffUtil.Callback() {
private var oldList: List<Any> = emptyList()
private var newList: List<Any> = emptyList()
fun setList(oldList: List<Any>, newList: List<Any>) {
this.oldList = oldList
this.newList = newList
}
override fun getOldListSize(): Int = oldList.size
override fun getNewListSize(): Int = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
}
class GeneralRecyclerView<T : Any>(
private val diffCallback: DiffCallback,
@LayoutRes private val holderResId: Int,
@IdRes private val specificResViewId: Int? = null,
private val onBind: (T, View) -> Unit,
private val itemListener: (T, pos: Int, View) -> Unit = { _, _, _ -> kotlin.run {} },
private val specificViewListener: (T, pos: Int, View) -> Unit = { _, _, _ -> kotlin.run {} }
) : RecyclerView.Adapter<GeneralRecyclerView.ViewHolder<T>>() {
private val data = mutableListOf<T>()
override fun onCreateViewHolder(container: ViewGroup, position: Int): ViewHolder<T> {
val layoutInflater = LayoutInflater.from(container.context)
val view = layoutInflater.inflate(holderResId, container, false)
var specificView: View? = null
specificResViewId?.let {
specificView = view.findViewById(it)
}
return ViewHolder(view, specificView)
}
override fun onBindViewHolder(viewHolder: ViewHolder<T>, position: Int) {
viewHolder.bindView(
data[viewHolder.adapterPosition],
onBind,
itemListener,
specificViewListener
)
}
override fun getItemCount(): Int = data.size
fun setData(datas: List<T>) {
calculateDiff(datas)
}
fun addData(newDatas: List<T>) {
val list = ArrayList(this.data)
list.addAll(newDatas)
calculateDiff(list)
}
fun refreshList() {
calculateDiff(data)
}
fun getData(): List<T> = this.data
fun clearData() {
calculateDiff(emptyList())
}
private fun calculateDiff(newData: List<T>) {
diffCallback.setList(data, newData)
val result = DiffUtil.calculateDiff(diffCallback)
with(data) {
clear()
addAll(newData)
}
result.dispatchUpdatesTo(this)
}
class ViewHolder<T : Any>(view: View, private val specificView: View? = null) :
RecyclerView.ViewHolder(view) {
private var itemPosition: Int = 0
fun bindView(
data: T,
onBind: (T, View) -> Unit,
itemListener: (T, pos: Int, View) -> Unit,
specificViewListener: (T, pos: Int, View) -> Unit
) {
itemPosition = adapterPosition
with(itemView) {
onBind.invoke(data, this)
setOnClickListener {
itemListener.invoke(data, adapterPosition, this)
}
}
specificView?.setOnClickListener {
specificViewListener.invoke(data, adapterPosition, itemView)
}
}
}
}
@swarawan
Copy link
Author

swarawan commented Jan 1, 2021

How to use:

private val studentDataAdapter by lazy {
        GeneralRecyclerView<SchoolInformationEntity>(
            diffCallback = diffCallback,
            holderResId = R.layout.item_student_confirmation,
            onBind = { data, view ->
                setupStudentData(data, view)
            }
        )
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment