android-recyclerview - Android Paging library 3 在滚动时插入新项目时抛出异常
问题描述
我正在使用 Paging library 3 开发一个 Android 聊天应用程序androidx.paging:paging-runtime-ktx:3.0.0-alpha12
分页库从 Room 数据库中检索聊天消息。
当我在 Room 数据库中的 ChatMessage 表中插入新的聊天消息时,在滚动聊天消息的回收器视图时,它会根据下面的 GIF 引发异常。发送按钮只是将一个新项目插入到 ChatMessage 表中。
这是错误日志。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.beeswork.balance, PID: 24171
java.lang.UnsupportedOperationException: Stable ids are unsupported on PagingDataAdapter.
at androidx.paging.PagingDataAdapter.setHasStableIds(PagingDataAdapter.kt:127)
at com.beeswork.balance.ui.chat.ChatFragment.setupChatRecyclerView(ChatFragment.kt:71)
at com.beeswork.balance.ui.chat.ChatFragment.access$setupChatRecyclerView(ChatFragment.kt:24)
at com.beeswork.balance.ui.chat.ChatFragment$bindUI$1.invokeSuspend(ChatFragment.kt:58)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Disconnected from the target VM, address: 'localhost', transport: 'socket'
这是在聊天片段中设置聊天回收器视图的代码
private fun setupChatRecyclerView() {
chatPagingAdapter = ChatPagingAdapter()
rvChat.adapter = chatPagingAdapter
val layoutManager = LinearLayoutManager(this@ChatFragment.context)
layoutManager.orientation = LinearLayoutManager.VERTICAL
layoutManager.reverseLayout = true
rvChat.layoutManager = layoutManager
lifecycleScope.launch {
viewModel.chatMessages.collectLatest {
chatPagingAdapter.submitData(it)
}
}
}
这是 ChatViewModel 中的 chatMessages
val chatMessages = Pager(
PagingConfig(
pageSize = 30,
enablePlaceholders = false,
maxSize = 150
)
) {
balanceRepository.getChatMessages(chatId)
}.flow.cachedIn(viewModelScope)
这是 ChatDAO 中的查询
@Query("select * from chatMessage where chatId = :chatId order by case when id is null then 0 else 1 end, id desc, messageId desc")
fun getChatMessages(chatId: Long): PagingSource<Int, ChatMessage>
这是 ChatPagingAdapter 扩展了 PagingDataAdapter
class ChatPagingAdapter : PagingDataAdapter<ChatMessage, ChatPagingAdapter.MessageViewHolder>(
diffCallback
) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
return when (viewType) {
ChatMessage.Status.RECEIVED.ordinal -> MessageViewHolder(parent.inflate(R.layout.item_chat_message_received))
ChatMessage.Status.SENT.ordinal -> MessageViewHolder(parent.inflate(R.layout.item_chat_message_sent))
else -> MessageViewHolder(parent.inflate(R.layout.item_chat_message_received))
}
}
override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
getItem(position)?.let {
when (holder.itemViewType) {
ChatMessage.Status.RECEIVED.ordinal -> holder.bindMessageReceived(it)
ChatMessage.Status.SENT.ordinal -> holder.bindMessageSent(it)
}
}
}
override fun getItemViewType(position: Int): Int {
return getItem(position)?.let {
return if (it.status == ChatMessage.Status.RECEIVED) ChatMessage.Status.RECEIVED.ordinal else ChatMessage.Status.SENT.ordinal
} ?: kotlin.run {
return ChatMessage.Status.RECEIVED.ordinal
}
}
companion object {
private val diffCallback = object : DiffUtil.ItemCallback<ChatMessage>() {
override fun areItemsTheSame(oldItem: ChatMessage, newItem: ChatMessage): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ChatMessage, newItem: ChatMessage): Boolean =
oldItem == newItem
}
}
class MessageViewHolder(
itemView: View
) : RecyclerView.ViewHolder(itemView) {
fun bind {...}
}
}
这里有问题
- 我可以在向聊天消息表插入新项目时保持滚动吗?
- 如果不可能,那么我该如何解决异常呢?
解决方案
推荐阅读
- vb.net - Visual Studio 2019 错误 BC30311 类型“VehicleMake”的值无法转换为“VehicleContext”
- javascript - 如何刷新角度组件
- android - Android MVVM:在特定情况下未从 MediatorLiveData 设置数据绑定值
- django - 注册新问题时如何向特定用户发送电子邮件
- r - 在 R 中根据两个参数(包括日期)查找数据
- c# - 我有一个包含多个字段的表单,并希望在提交事件时生成一个带有表单字段值的 pdf 文件
- excel - 另存为 PDF 时更改日期格式
- angular - 如何总结角度总数?
- python-3.x - 有没有办法将变量作为计数器传递给python中的列表索引?
- python-3.7 - 珠宝库存重量管理系统程序