RecyclerView, DiffUtil и странная анимация - PullRequest
0 голосов
/ 12 июня 2018

У меня есть приложение чата, работающее с веб-сокетами.Через веб-сокет я получаю сообщение, которое сохраняю в базу данных, таблицу сообщений и обновляю 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() })
    }
}

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...