Skip to content

Commit

Permalink
Switch to ListAdapter (replacing RecyclerView.Adapter) (#321)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyb3rko committed Nov 18, 2023
1 parent b6519d1 commit 0d423c1
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.github.gotify.MarkwonFactory
Expand All @@ -34,9 +36,8 @@ internal class ListMessageAdapter(
private val context: Context,
private val settings: Settings,
private val picasso: Picasso,
var items: List<MessageWithImage>,
private val delete: Delete
) : RecyclerView.Adapter<ListMessageAdapter.ViewHolder>() {
) : ListAdapter<MessageWithImage, ListMessageAdapter.ViewHolder>(DiffCallback) {
private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val markwon: Markwon = MarkwonFactory.createForMessage(context, picasso)

Expand Down Expand Up @@ -70,7 +71,7 @@ internal class ListMessageAdapter(
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val message = items[position]
val message = currentList[position]
if (Extras.useMarkdown(message.message)) {
holder.message.autoLinkMask = 0
markwon.setMarkdown(holder.message, message.message.message)
Expand All @@ -92,14 +93,12 @@ internal class ListMessageAdapter(
holder.date.setOnClickListener { holder.switchTimeFormat() }

holder.delete.setOnClickListener {
delete.delete(holder.adapterPosition, message.message, false)
delete.delete(message.message)
}
}

override fun getItemCount() = items.size

override fun getItemId(position: Int): Long {
val currentItem = items[position]
val currentItem = currentList[position]
return currentItem.message.id
}

Expand Down Expand Up @@ -184,7 +183,23 @@ internal class ListMessageAdapter(
}
}

object DiffCallback : DiffUtil.ItemCallback<MessageWithImage>() {
override fun areItemsTheSame(
oldItem: MessageWithImage,
newItem: MessageWithImage
): Boolean {
return oldItem.message.id == newItem.message.id
}

override fun areContentsTheSame(
oldItem: MessageWithImage,
newItem: MessageWithImage
): Boolean {
return oldItem == newItem
}
}

fun interface Delete {
fun delete(position: Int, message: Message, listAnimation: Boolean)
fun delete(message: Message)
}
}
49 changes: 18 additions & 31 deletions app/src/main/kotlin/com/github/gotify/messages/MessagesActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,9 @@ internal class MessagesActivity :
listMessageAdapter = ListMessageAdapter(
this,
viewModel.settings,
viewModel.picassoHandler.get(),
emptyList()
) { position, message, listAnimation ->
scheduleDeletion(
position,
message,
listAnimation
)
viewModel.picassoHandler.get()
) { message ->
scheduleDeletion(message)
}
addBackPressCallback()

Expand Down Expand Up @@ -329,7 +324,6 @@ internal class MessagesActivity :
}
}
}
listMessageAdapter.notifyDataSetChanged()
selectAppInMenu(binding.navView.menu.findItem(selectedIndex))
super.onResume()
}
Expand All @@ -348,20 +342,11 @@ internal class MessagesActivity :
}
}

private fun scheduleDeletion(
position: Int,
message: Message,
listAnimation: Boolean
) {
private fun scheduleDeletion(message: Message) {
val adapter = binding.messagesView.adapter as ListMessageAdapter
val messages = viewModel.messages
messages.deleteLocal(message)
adapter.items = messages[viewModel.appId]
if (listAnimation) {
adapter.notifyItemRemoved(position)
} else {
adapter.notifyDataSetChanged()
}
adapter.updateList(messages[viewModel.appId])
showDeletionSnackbar()
}

Expand All @@ -371,13 +356,7 @@ internal class MessagesActivity :
if (deletion != null) {
val adapter = binding.messagesView.adapter as ListMessageAdapter
val appId = viewModel.appId
adapter.items = messages[appId]
val insertPosition = if (appId == MessageState.ALL_MESSAGES) {
deletion.allPosition
} else {
deletion.appPosition
}
adapter.notifyItemInserted(insertPosition)
adapter.updateList(messages[appId])
}
}

Expand Down Expand Up @@ -432,8 +411,8 @@ internal class MessagesActivity :

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
val message = adapter.items[position]
scheduleDeletion(position, message.message, true)
val message = adapter.currentList[position]
scheduleDeletion(message.message)
}

override fun onChildDraw(
Expand Down Expand Up @@ -649,8 +628,16 @@ internal class MessagesActivity :
binding.flipper.displayedChild = 0
}
val adapter = binding.messagesView.adapter as ListMessageAdapter
adapter.items = messageWithImages
adapter.notifyDataSetChanged()
adapter.updateList(messageWithImages)
}

private fun ListMessageAdapter.updateList(list: List<MessageWithImage>) {
this.submitList(if (this.currentList == list) list.toList() else list) {
val topChild = binding.messagesView.getChildAt(0)
if (topChild != null && topChild.top == 0) {
binding.messagesView.scrollToPosition(0)
}
}
}

companion object {
Expand Down

0 comments on commit 0d423c1

Please sign in to comment.