问题
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);
}
回答1:
As I understand, the question is: how to preload images with Glide? 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();
}
来源:https://stackoverflow.com/questions/62562877/glide-how-to-preload-images-and-get-confirmation-that-it-is-stored-in-cache