首页 > 解决方案 > 更新可观察排放的回收器视图适配器

问题描述

在开发聊天应用程序时,图像处理的必要性——它的下载和上传——已经面临。处理本身是在 RxJava2 的 Observables 的帮助下完成的;而下载或上传的命令是从 RecyclerView Adapter 的 OnBindViewHolder() 完成的。

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    if (currentlyUsedPositionToMessageMap.containsKey(position)) {
        val message = currentlyUsedPositionToMessageMap[position]
        when (message) {
            is TextMessage -> (holder as TextMessageViewHolder).bind(message)
            is ImageMessage -> (holder as ImageMessageViewHolder).bind(message)
        }
    } else {
        val (messageType, downloadableMessage) = downloadableMessages[position]

        disposables += downloadableMessage                    //Observable
            .subscribeBy(
                onNext = {
                    currentlyUsedPositionToMessageMap[position] = it
                    notifyItemChanged(position)
                },
                onError = {
                    Log.e(LOG_TAG, Log.getStackTraceString(it))
                }
            )

        when (messageType){
            "image" -> (holder as ImageMessageViewHolder).showDefaultAnimation()
            "text" -> (holder as TextMessageViewHolder).showDefaultAnimation()
        }
    }
}

上面代码的想法是:如果已经下载了图像(或文本),则用数据填充 ViewHolder,否则设置下载任务并使 ViewHolder 显示一些默认动画。

面临的问题:下载任务完成后无法更新可见的 ViewHolders,因为 notifyItemChanged(position) 导致以下错误:

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView

那么,我该如何解决这个异常呢?换句话说,在使用下载的图像成功下载图像后,如何在 [位置] (如果可见)更新 ViewHolder?

标签: androidrx-javarx-java2android-recyclerview

解决方案


发生了什么?简而言之:

更新是在未完全加载的 RecyclerView 上完成的,导致异常:

RecyclerView 正在计算布局或滚动时无法调用此方法

注:“此方法”指的是 notifyItemChanged(position) 用于项目更新


阐述:

问题与图像处理无关,而与文本处理有关。应用程序设计是,如果当前项目是可下载的图像,则去下载它;如果它已经缓存了文本,则返回带有来自 Android 主线程的文本的新 Observable。因此,在 Observable 的主线程上创建与 RecyclerView ViewHolder 数据填充竞争。因此,当 Observable 返回时,RecyclerView 没有加载它必须在其他时间加载的所有项目,这导致在未完成的 RecyclerView 上执行更新操作。因此,例外!


推荐阅读