目录

viewBinding配合Glide遇到的小坑

目录

一直在用 kotlin synthetic, 今天才去尝试大规模切换到viewbinding, 结果先自己做了一个demo, 就遇到了小坑

今天打算写一个相册点击缩放到展示详情的fragment的demo, 本来我很自信的用"熟悉"的glide去加载图片:

1
Glide.with(this).load(url).into(this) // this 这里指代 imageView

https://cdn.jsdelivr.net/gh/zsqw123/cdn@master/picCDN/20210127191244.png

结果发现: ?? 为什么图片不加载, 于是我尝试了另外一种方式:

1
2
3
4
5
6
Glide.with(this).asBitmap().load(url).into(object : CustomTarget<Bitmap>() {
    override fun onLoadCleared(placeholder: Drawable?) {}
    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
        this.setImageBitmap(resource)
    }
})

神奇的事情发生了, 这种方式的图片就加载成功了, 但是很显然这种方式并不优雅, 且容易 OOM.

https://cdn.jsdelivr.net/gh/zsqw123/cdn@master/picCDN/20210127191621.webp

在查看 Glide.with 源代码之后 (事实上查看了很多, 最终发现是这里有问题hhhhc), 发现如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/*
 * ...
 * <p>This method will not work if the View is not attached. Prefer the Activity and Fragment
 * variants unless you're loading in a View subclass.
 * ...
 *
 * @param view The view to search for a containing Fragment or Activity from.
 * @return A RequestManager that can be used to start a load.
 */
@NonNull
public static RequestManager with(@NonNull View view) {
  return getRetriever(view.getContext()).get(view);
}

在上面我们可以看到, View 必须 attached 到其 parent 上面, 于是我顿悟自己仿佛找到了原因, 将 recyclerViewAdapter 中的 viewBinding:

1
binding = RootRvItemBinding.inflate(LayoutInflater.from(parent.context))

改为如下:

1
binding = RootRvItemBinding.inflate(LayoutInflater.from(parent.context), parent, true)

结果报错:

1
    java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)

事实上, 在 Inflate 时, 如果我们已经定义了 parent 属性, 那么 recyclerViewAdapter 会自动帮我们 attach 到 parent 上, 因此第三个参数我们应该设置为 false :

1
binding = RootRvItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)

编译通过, 图片顺利加载.