Switch to ListAdapter (replacing RecyclerView.Adapter) (#321)

This commit is contained in:
Niko Diamadis
2023-11-18 15:13:44 +01:00
committed by GitHub
parent b6519d1de4
commit 0d423c1ce4
2 changed files with 41 additions and 39 deletions

View File

@@ -14,6 +14,8 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.github.gotify.MarkwonFactory import com.github.gotify.MarkwonFactory
@@ -34,9 +36,8 @@ internal class ListMessageAdapter(
private val context: Context, private val context: Context,
private val settings: Settings, private val settings: Settings,
private val picasso: Picasso, private val picasso: Picasso,
var items: List<MessageWithImage>,
private val delete: Delete private val delete: Delete
) : RecyclerView.Adapter<ListMessageAdapter.ViewHolder>() { ) : ListAdapter<MessageWithImage, ListMessageAdapter.ViewHolder>(DiffCallback) {
private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val markwon: Markwon = MarkwonFactory.createForMessage(context, picasso) private val markwon: Markwon = MarkwonFactory.createForMessage(context, picasso)
@@ -70,7 +71,7 @@ internal class ListMessageAdapter(
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val message = items[position] val message = currentList[position]
if (Extras.useMarkdown(message.message)) { if (Extras.useMarkdown(message.message)) {
holder.message.autoLinkMask = 0 holder.message.autoLinkMask = 0
markwon.setMarkdown(holder.message, message.message.message) markwon.setMarkdown(holder.message, message.message.message)
@@ -92,14 +93,12 @@ internal class ListMessageAdapter(
holder.date.setOnClickListener { holder.switchTimeFormat() } holder.date.setOnClickListener { holder.switchTimeFormat() }
holder.delete.setOnClickListener { 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 { override fun getItemId(position: Int): Long {
val currentItem = items[position] val currentItem = currentList[position]
return currentItem.message.id return currentItem.message.id
} }
@@ -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 interface Delete {
fun delete(position: Int, message: Message, listAnimation: Boolean) fun delete(message: Message)
} }
} }

View File

@@ -101,14 +101,9 @@ internal class MessagesActivity :
listMessageAdapter = ListMessageAdapter( listMessageAdapter = ListMessageAdapter(
this, this,
viewModel.settings, viewModel.settings,
viewModel.picassoHandler.get(), viewModel.picassoHandler.get()
emptyList() ) { message ->
) { position, message, listAnimation -> scheduleDeletion(message)
scheduleDeletion(
position,
message,
listAnimation
)
} }
addBackPressCallback() addBackPressCallback()
@@ -329,7 +324,6 @@ internal class MessagesActivity :
} }
} }
} }
listMessageAdapter.notifyDataSetChanged()
selectAppInMenu(binding.navView.menu.findItem(selectedIndex)) selectAppInMenu(binding.navView.menu.findItem(selectedIndex))
super.onResume() super.onResume()
} }
@@ -348,20 +342,11 @@ internal class MessagesActivity :
} }
} }
private fun scheduleDeletion( private fun scheduleDeletion(message: Message) {
position: Int,
message: Message,
listAnimation: Boolean
) {
val adapter = binding.messagesView.adapter as ListMessageAdapter val adapter = binding.messagesView.adapter as ListMessageAdapter
val messages = viewModel.messages val messages = viewModel.messages
messages.deleteLocal(message) messages.deleteLocal(message)
adapter.items = messages[viewModel.appId] adapter.updateList(messages[viewModel.appId])
if (listAnimation) {
adapter.notifyItemRemoved(position)
} else {
adapter.notifyDataSetChanged()
}
showDeletionSnackbar() showDeletionSnackbar()
} }
@@ -371,13 +356,7 @@ internal class MessagesActivity :
if (deletion != null) { if (deletion != null) {
val adapter = binding.messagesView.adapter as ListMessageAdapter val adapter = binding.messagesView.adapter as ListMessageAdapter
val appId = viewModel.appId val appId = viewModel.appId
adapter.items = messages[appId] adapter.updateList(messages[appId])
val insertPosition = if (appId == MessageState.ALL_MESSAGES) {
deletion.allPosition
} else {
deletion.appPosition
}
adapter.notifyItemInserted(insertPosition)
} }
} }
@@ -432,8 +411,8 @@ internal class MessagesActivity :
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition val position = viewHolder.adapterPosition
val message = adapter.items[position] val message = adapter.currentList[position]
scheduleDeletion(position, message.message, true) scheduleDeletion(message.message)
} }
override fun onChildDraw( override fun onChildDraw(
@@ -649,8 +628,16 @@ internal class MessagesActivity :
binding.flipper.displayedChild = 0 binding.flipper.displayedChild = 0
} }
val adapter = binding.messagesView.adapter as ListMessageAdapter val adapter = binding.messagesView.adapter as ListMessageAdapter
adapter.items = messageWithImages adapter.updateList(messageWithImages)
adapter.notifyDataSetChanged() }
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 { companion object {