Skip to content

Commit f1429a6

Browse files
I've completed the refactor to migrate AdapterJoinedMember to ListAdapter. Here is a summary of my changes:
I refactored `AdapterJoinedMember` from a standard `RecyclerView.Adapter` to `ListAdapter` to leverage `DiffUtil` for more efficient list updates. - I changed the superclass to `ListAdapter<JoinedMemberData, ViewHolderUser>`. - I added a `DiffUtil.ItemCallback` to handle item and content comparisons. - I replaced manual `MutableList` management by passing new lists to the adapter, ensuring they are handled immutably. - I updated the `removeMember`, `updateLeadership`, and `updateData` methods to create new lists and pass them to the adapter, which triggers efficient, fine-grained UI updates. - This change eliminates whole-list redraws caused by `notifyDataSetChanged()`, improving performance and simplifying the adapter's logic.
1 parent 83a17ba commit f1429a6

File tree

1 file changed

+23
-50
lines changed

1 file changed

+23
-50
lines changed

app/src/main/java/org/ole/planet/myplanet/ui/team/teamMember/AdapterJoinedMember.kt

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.ole.planet.myplanet.ui.team.teamMember
22

3-
import android.annotation.SuppressLint
43
import android.content.Context
54
import android.view.LayoutInflater
65
import android.view.View
@@ -10,12 +9,13 @@ import android.widget.TextView
109
import androidx.appcompat.app.AlertDialog
1110
import androidx.appcompat.app.AppCompatActivity
1211
import androidx.core.content.ContextCompat
13-
import androidx.recyclerview.widget.RecyclerView
12+
import androidx.recyclerview.widget.ListAdapter
1413
import com.bumptech.glide.Glide
1514
import org.ole.planet.myplanet.R
1615
import org.ole.planet.myplanet.databinding.RowJoinedUserBinding
1716
import org.ole.planet.myplanet.model.RealmUserModel
1817
import org.ole.planet.myplanet.ui.navigation.NavigationHelper
18+
import org.ole.planet.myplanet.utilities.DiffUtils
1919

2020
data class JoinedMemberData(
2121
val user: RealmUserModel,
@@ -28,10 +28,17 @@ data class JoinedMemberData(
2828

2929
class AdapterJoinedMember(
3030
private val context: Context,
31-
private val list: MutableList<JoinedMemberData>,
3231
private var isLoggedInUserTeamLeader: Boolean,
3332
private val actionListener: MemberActionListener
34-
) : RecyclerView.Adapter<AdapterJoinedMember.ViewHolderUser>() {
33+
) : ListAdapter<JoinedMemberData, AdapterJoinedMember.ViewHolderUser>(JoinedMemberDataCallback) {
34+
35+
companion object {
36+
private val JoinedMemberDataCallback =
37+
DiffUtils.itemCallback<JoinedMemberData>(
38+
areItemsTheSame = { oldItem, newItem -> oldItem.user.id == newItem.user.id },
39+
areContentsTheSame = { oldItem, newItem -> oldItem == newItem }
40+
)
41+
}
3542

3643
interface MemberActionListener {
3744
fun onRemoveMember(member: JoinedMemberData, position: Int)
@@ -44,7 +51,7 @@ class AdapterJoinedMember(
4451
}
4552

4653
override fun onBindViewHolder(holder: ViewHolderUser, position: Int) {
47-
val memberData = list[position]
54+
val memberData = getItem(position)
4855
val member = memberData.user
4956
val binding = holder.binding
5057

@@ -103,7 +110,7 @@ class AdapterJoinedMember(
103110
binding: RowJoinedUserBinding,
104111
position: Int
105112
) {
106-
if (isLoggedInUserTeamLeader && list.size > 1) {
113+
if (isLoggedInUserTeamLeader && currentList.size > 1) {
107114
binding.icMore.visibility = View.VISIBLE
108115
binding.icMore.setOnClickListener {
109116
val overflowMenuOptions = arrayOf(
@@ -125,8 +132,8 @@ class AdapterJoinedMember(
125132
}
126133
builder.setAdapter(adapter) { _, i ->
127134
when (i) {
128-
0 -> actionListener.onRemoveMember(list[position], position)
129-
1 -> actionListener.onMakeLeader(list[position])
135+
0 -> actionListener.onRemoveMember(getItem(position), position)
136+
1 -> actionListener.onMakeLeader(getItem(position))
130137
}
131138
}.setNegativeButton(R.string.dismiss, null).show()
132139
}
@@ -135,57 +142,23 @@ class AdapterJoinedMember(
135142
}
136143
}
137144

138-
override fun getItemCount(): Int = list.size
139-
140-
@SuppressLint("NotifyDataSetChanged")
141-
fun updateData(newList: MutableList<JoinedMemberData>, isLoggedInUserTeamLeader: Boolean) {
142-
list.clear()
143-
list.addAll(newList)
145+
fun updateData(newList: List<JoinedMemberData>, isLoggedInUserTeamLeader: Boolean) {
144146
this.isLoggedInUserTeamLeader = isLoggedInUserTeamLeader
145-
notifyDataSetChanged()
147+
submitList(newList.sortedByDescending { it.isLeader })
146148
}
147149

148150
fun removeMember(memberId: String) {
149-
val position = list.indexOfFirst { it.user.id == memberId }
150-
if (position != -1) {
151-
list.removeAt(position)
152-
notifyItemRemoved(position)
153-
154-
if (list.isNotEmpty()) {
155-
notifyItemRangeChanged(0, list.size)
156-
}
157-
}
151+
val newList = currentList.filterNot { it.user.id == memberId }
152+
submitList(newList)
158153
}
159154

160155
fun updateLeadership(loggedInUserId: String?, newLeaderId: String) {
161-
var oldLeaderPos = -1
162-
var newLeaderPos = -1
163-
164-
list.forEachIndexed { index, memberData ->
165-
if (memberData.isLeader) {
166-
memberData.isLeader = false
167-
oldLeaderPos = index
168-
}
169-
if (memberData.user.id == newLeaderId) {
170-
memberData.isLeader = true
171-
newLeaderPos = index
172-
}
173-
}
156+
val newList = currentList.map {
157+
it.copy(isLeader = it.user.id == newLeaderId)
158+
}.sortedByDescending { it.isLeader }
174159

175160
isLoggedInUserTeamLeader = (loggedInUserId == newLeaderId)
176-
177-
if (newLeaderPos > 0) {
178-
val newLeader = list.removeAt(newLeaderPos)
179-
list.add(0, newLeader)
180-
notifyItemMoved(newLeaderPos, 0)
181-
}
182-
183-
if (oldLeaderPos != -1) notifyItemChanged(if (oldLeaderPos == 0) 1 else oldLeaderPos)
184-
notifyItemChanged(0)
185-
186-
if (list.size > 2) {
187-
notifyItemRangeChanged(1, list.size - 1)
188-
}
161+
submitList(newList)
189162
}
190163

191164
class ViewHolderUser(val binding: RowJoinedUserBinding) :

0 commit comments

Comments
 (0)