问题描述
我有一个RecyclerView
,每行里面有一个ImageView
,在这里我使用Glide
从URL设置图像.问题是,当我第一次打开并尝试滚动RecyclerView
时,仅下载该图像.显然,它将保存到缓存中,下次将不再下载.
我希望图像是第一次预加载的,这样当用户滚动时,他/她就不必等待.
请查看代码:
@Override
public void onBindViewHolder(PostAdapter.MyViewHolder holder, int position) {
try {
Post post = postArrayList.get(position);
if (checkNull(post.getDesc())) {
setText(holder.postDesc, postArrayList.get(position).getDesc());
} else if (checkNull(post.getUrl())) {
setImage(holder.postImage, postArrayList.get(position).getUrl());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setImage(ImageView image1, String str) {
image1.setVisibility(View.VISIBLE);
Glide.with(context).load(str).
diskCacheStrategy(DiskCacheStrategy.ALL)
.into(image1);
}
目前尚不清楚对话发生了.
这实际上非常简单,几乎与将图像加载到ImageView
中相同. Glide具有可用的preload()
函数,该函数将从给定的URL中预加载图像.选择最适合您情况的DiskCacheStrategy
.
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.preload();
如果要更改结果图像的大小,请使用preload(int width, int height)
.
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.preload(width, height);
如果您缓存的图像实际上没有缓存,请按照此解决方案添加自定义LruCache映射.
进行了一些测试
一项测试分别涉及三种不同的尺寸ImageView中.然后,在短暂的延迟之后,将同一张图片加载到100x100dp ImageView
中,并在另一个延迟后加载到300x300dp ImageView
.
测试表明,由于即时加载速度已将原始图像缓存到300x300dp ImageView
.
注意:恰好在图像加载开始之前弹出敬酒消息.
视频证明:
(如果视频链接断开,请尝试此链接).
更新(有点超出问题范围):如何等待直到所有图像都已预加载?
... rest of YourActivity class
private int imagesLoaded = 0;
private int totalImagesCount = 0;
private void preloadAllImages(ArrayList<String> imagesUrls) {
totalImagesCount = imagesUrls.size();
for (String url : imagesUrls) {
preloadImage(url);
}
}
private void preloadImage(String url) {
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
// Handle exceptions differently if you want
imagesLoaded++;
if (imagesLoaded == totalImagesCount) {
startMainActivity();
}
return true;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
imagesLoaded++;
if (imagesLoaded == totalImagesCount) {
startMainActivity();
}
return true;
}
})
.preload();
}
I have a RecyclerView
and inside of each row I have ImageView
where I'm using Glide
to set an image from URL. The problem is when the first time I open and try to scroll RecyclerView
then only that images are downloaded. Obviously it'll save to cache and next time it won't be downloaded again.
I'd like images to be preloaded for the first time so that when a user will scroll he/she won't have to wait.
Please see the code:
@Override
public void onBindViewHolder(PostAdapter.MyViewHolder holder, int position) {
try {
Post post = postArrayList.get(position);
if (checkNull(post.getDesc())) {
setText(holder.postDesc, postArrayList.get(position).getDesc());
} else if (checkNull(post.getUrl())) {
setImage(holder.postImage, postArrayList.get(position).getUrl());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setImage(ImageView image1, String str) {
image1.setVisibility(View.VISIBLE);
Glide.with(context).load(str).
diskCacheStrategy(DiskCacheStrategy.ALL)
.into(image1);
}
It wasn't clear before all the conversation happened.
This is actually quite simple and almost identical to loading an image into an ImageView
. Glide has a preload()
function available that will preload image from given URL. Select DiskCacheStrategy
that is most likely fits your situation.
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.preload();
Use preload(int width, int height)
if you want to change the size of the resulting image.
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.preload(width, height);
If your cached images do not actually cache follow this solution to add custom LruCache map.
A little test conducted
A test involved three different sizes ImageView
s 100x100, 200x200 and 300x300 DP respectively. Glide was tasked to load an 8K image into 200x200dp ImageView
. Then after a short delay load the same image into the 100x100dp ImageView
and after another delay into 300x300dp ImageView
.
The test shows that the original image was cached due to instant loading speed into 300x300dp ImageView
.
Note: Toast messages pop-up right before the image loading starts.
Video proof:
(If the video link is broken try this link).
Update (a bit out of question scope): how to wait until all images are preloaded?
... rest of YourActivity class
private int imagesLoaded = 0;
private int totalImagesCount = 0;
private void preloadAllImages(ArrayList<String> imagesUrls) {
totalImagesCount = imagesUrls.size();
for (String url : imagesUrls) {
preloadImage(url);
}
}
private void preloadImage(String url) {
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
// Handle exceptions differently if you want
imagesLoaded++;
if (imagesLoaded == totalImagesCount) {
startMainActivity();
}
return true;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
imagesLoaded++;
if (imagesLoaded == totalImagesCount) {
startMainActivity();
}
return true;
}
})
.preload();
}
这篇关于Glide:如何预加载图像并确认其已存储在缓存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!