ImageView RecyclerView 延迟加载

Posted

技术标签:

【中文标题】ImageView RecyclerView 延迟加载【英文标题】:ImageView RecyclerView Lazy Load 【发布时间】:2018-11-21 10:11:10 【问题描述】:

我有一个 RecyclerViewAdapter,它在 onBindViewHolder 中,我调用 AsyncTask 从 Google Cloud Storage 下载所需的图像。

RecyclerViewAdapter 中有一些项目需要相同的图像。我试图通过仅在本地文件存储中不存在图像时才下载图像来解决此问题;否则,如果是,则使用已下载的图像。

现在发生的情况是,如果 RecyclerView 中有多个项目在足够近的同一时间调用相同的图像,则其中一个项目 ImageView 将只是空白/白色,但其余项目将正确显示图像。

我希望能够捕捉到这种情况,只需使用Thread.sleep,然后再次尝试获取/使用该文件,但我没有抛出任何异常或任何东西,所以我不确定如何捕捉那个场景来处理它。

我可以在 logcat 中看到的唯一看起来很有帮助的是以下内容:

D/skia: --- Failed to create image decoder with message 'unimplemented'

但是它没有抛出异常,它只是将其记录为消息。

但它确实表明图像解码存在问题。所以我检查了BitmapFactory.decodeFile 文档,它说如果它无法解码它会返回一个空值。所以我在尝试解码后尝试检查我的位图是否为空,但它从未命中该 IF 语句,这意味着它永远不会返回空,所以我不知道该怎么做。

new Getlogos(holder.logoImageView.getTag().toString(), holder.itemView.getContext(), new Getlogos.AsyncResponse() 
    @Override
    public void returnBitmapURI(String URI, String tag) 
        if (holder.logoImageView != null && holder.logoImageView.getTag().toString().equals(tag)) 
            if (URI.contains("drawable://")) 
                int id = Integer.parseInt(URI.substring(11));
                Bitmap myBitmap = BitmapFactory.decodeResource(context.getResources(), id);
                holder.logoImageView.setImageBitmap(myBitmap);
             else 
                Bitmap myBitmap = BitmapFactory.decodeFile(URI);
                holder.logoImageView.setImageBitmap(myBitmap);
            
        
    
).execute();

此问题仅有时会发生,并且不会始终发生在同一图像上。它通常在一些具有相同图像要下载/使用的项目之间变化。有时它根本不会发生。

任何人都可以了解该skia消息的来源以及当它无法解码时我如何捕获它,以便我可以处理它?

【问题讨论】:

谷歌存储是指firebase存储? 我的意思是Google Cloud Storage 您是否有理由不想为此使用库,例如​​ Picasso Image Loader.. Picasso 图像加载器将为您处理所有这些东西,您可以通过单个设置图像源oneliner。 除非必须,否则我尽量不使用库。我想我认为这可能有助于我了解或了解更多关于它是如何运作的。 当你从 uri 设置位图时,它会加载全宽和全高的整个图像,所以首先裁剪位图并相对于 imageview 进行设置,而不是使用 glide 库 【参考方案1】:

使用 Glide 在 recyclerView 中显示图片

将此依赖项添加到 build.gradle

implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

onBindViewHolder 内部

请求选项以显示错误图像、占位符图像等。 CircularProgressDrawable 用于占位符可绘制(可选)

val circularProgressDrawable = CircularProgressDrawable(mContext)
        circularProgressDrawable.strokeWidth = 5f
        circularProgressDrawable.centerRadius = 30f
        circularProgressDrawable.start()

        val requestOption : RequestOptions = RequestOptions()
                .placeholder(circularProgressDrawable)
                .error(R.drawable.ic_error_1)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .priority(Priority.HIGH)
                .dontAnimate()
                .dontTransform()

如下所示初始化Glide

Glide.with(mContext)
            .load(model.imageUrl)
            .apply(requestOption)
            .into(holder.imageView!!)

【讨论】:

尽管这并不能真正回答我的问题,但它是解决我自己实现所需功能的问题的可用解决方法,因此我将其标记为答案。感谢您提供有关如何实现 Glide 的示例代码。我的 RecyclerViewAdapter 有点慢,但经过一些调整后,它现在看起来确实可以正常运行了。【参考方案2】:

如果是这样发生的:

创建图像解码器失败,消息“未实现”

通过判断“bitmap == null?”来捕获异常 喜欢下面的代码:

我的英文不是很好,希望你能听懂我说的话!

【讨论】:

以上是关于ImageView RecyclerView 延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

如何根据特定条件在 RecyclerView 上为某些项目隐藏 ImageView?

如何将 videoView 与 imageView 和 recyclerView 一起制作动画?

如何通过firebase实时数据库永久隐藏RecyclerView中的imageview

在 RecyclerView 上膨胀类 ImageView 时出错

Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑

Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑