У меня есть приложение чата, работающее с веб-сокетами.Через веб-сокет я получаю сообщение, которое сохраняю в базу данных, таблицу сообщений и обновляю last message id
в таблице разговоров.Теперь оба сохранения уведомят курсор.Поэтому я звоню updateDate
дважды.Они будут работать последовательно, в правильном порядке и в правильных потоках.Тем не менее, я думаю, анимация накладывается и делает странный эффект видимым в прикрепленном видео на YouTube (видимом из сообщения «i»).Кто-нибудь может точно определить мою проблему или дать мне решение?
Я использую rxjava для создания потоков и удаления из очереди для накопления обновлений, при этом всегда получаю только последнее обновление из очереди.Вдохновение от vlc здесь
RecyclerView укладывается с конца, и если пользователь прокручивается до дна, то при появлении нового сообщения запускается анимация прокрутки до дна.
Фрагмент
adapter = ChatMessageAdapter()
recycler.apply {
adapter = this@ChatDetailFragment.adapter
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false).apply { stackFromEnd = true }
}
ChatMessageAdapter
private val pendingUpdates: ArrayDeque<Single<Pair<MutableList<ChatItemHolder>, DiffUtil.DiffResult>>> = ArrayDeque()
@MainThread
fun updateData(msgs: MutableList<ChatMessage>, onDone: () -> Unit) {
pendingUpdates.add(
internalUpdate(msgs)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess {
items.clear()
items.addAll(it.first)
it.second.dispatchUpdatesTo(this@ChatMessageAdapter)
onDone()
}
)
if (pendingUpdates.size == 1) pendingUpdates.peek().subscribe(Consumer {processQueue()})
}
private fun internalUpdate(msgs: MutableList<ChatMessage>) = Single.create<Pair<MutableList<ChatItemHolder>, DiffUtil.DiffResult>> {
val newItems = temp(msgs) // transforming function from ChatMessage[] to ChatItemHolder[]
val result = DiffUtil.calculateDiff(DiffUtilCallback(newItems, items), true)
it.onSuccess(Pair(newItems, result))
}
@MainThread
private fun processQueue() {
pendingUpdates.remove()
if (!pendingUpdates.isEmpty()) {
if (pendingUpdates.size > 1) {
val last = pendingUpdates.peekLast()
pendingUpdates.clear()
pendingUpdates.add(last)
}
pendingUpdates.peek().subscribe(Consumer { processQueue() })
}
}
Спасибо!