Skip to content

Instantly share code, notes, and snippets.

@rommansabbir
Created April 11, 2021 14:09
Show Gist options
  • Save rommansabbir/16e6f6db8c83fdfa9ef2045ed2245116 to your computer and use it in GitHub Desktop.
Save rommansabbir/16e6f6db8c83fdfa9ef2045ed2245116 to your computer and use it in GitHub Desktop.
Android RecyclerView: Async DiffUtill
@Singleton
class PatientUserChatAdapter @Inject constructor() :
RecyclerView.Adapter<PatientUserChatViewHolder>() {
//
private var dataSet: MutableList<UserChatDataModel> = mutableListOf()
private var callback: PatientUserChatSelectionCallback? = null
//Register for action callback
fun setActionCallback(callback: PatientUserChatSelectionCallback? = null) {
this.callback = callback
}
/**
* Set list of [UserChatDataModel] to the adapter to show on the UI.
*
* Do all the logical operation under a [Dispatchers.Default] scope.
*
* Dispatch the update under a [Dispatchers.Main] scope.
*
* @param list, [MutableList<UserChatDataModel>]
*/
fun setDataSet(list: MutableList<UserChatDataModel>) {
CoroutineScope(Dispatchers.Default).launch {
Logger.d("PatientUserChatAdapter : Working on Background")
val callback = DiffUtil.calculateDiff(DiffCallback(list, dataSet))
this@PatientUserChatAdapter.dataSet.clear()
this@PatientUserChatAdapter.dataSet.addAll(list)
withContext(Dispatchers.Main) {
callback.dispatchUpdatesTo(this@PatientUserChatAdapter)
Logger.d("PatientUserChatAdapter : Updating on Foreground")
}
}
}
//Clear the whole data set
fun onDestroy() {
setDataSet(mutableListOf())
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PatientUserChatViewHolder =
PatientUserChatViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.content_item_patient_user_chat,
parent,
false
)
)
override fun onBindViewHolder(holder: PatientUserChatViewHolder, position: Int) {
callback?.let {
holder.bindView(position, dataSet, it)
}
}
override fun getItemCount(): Int = dataSet.size
//DiffUtil callback
private inner class DiffCallback(
private val newList: MutableList<UserChatDataModel>,
private val oldList: MutableList<UserChatDataModel>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return newList[newItemPosition] == oldList[oldItemPosition]
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return newList[newItemPosition] == oldList[oldItemPosition]
}
}
}
//View Holder Class
class PatientUserChatViewHolder(private val binding: ContentItemPatientUserChatBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bindView(
position: Int,
list: MutableList<UserChatDataModel>,
callback: PatientUserChatSelectionCallback
) {
binding.model = list[position]
binding.callback = callback
binding.executePendingBindings()
}
}
//XML Reference
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="model"
type=".UserChatDataModel" />
<variable
name="callback"
type=".PatientUserChatSelectionCallback" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GlideImageView
android:id="@+id/glideImageView"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:setImageUrlCircle="@{model.creator_avatar}"
app:srcCompat="@drawable/ic_profile_picture" />
<ImageButton
android:id="@+id/glideImageView2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="8dp"
android:background="?actionBarItemBackground"
android:onClick="@{() -> callback.onSelection(model)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_baseline_keyboard_arrow_right_24" />
<TextView
android:id="@+id/textView57"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="marquee"
android:singleLine="true"
android:text="@{model.creator_displayname}"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/glideImageView2"
app:layout_constraintStart_toEndOf="@+id/glideImageView"
app:layout_constraintTop_toTopOf="@+id/glideImageView"
tools:text="TextView" />
<TextView
android:id="@+id/textView58"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:maxLines="2"
android:text="@{model.lastMessageSent}"
app:layout_constraintEnd_toStartOf="@+id/glideImageView2"
app:layout_constraintStart_toEndOf="@+id/glideImageView"
app:layout_constraintTop_toBottomOf="@+id/textView57"
tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment