如何正确地将 firebase 存储图像下载到 recyclerView
How to correctly download firebase storage images into recycelrView
我有 recyclerview 并且在每一行中我都有一个我加载的图像 firebase storage。图像加载似乎影响了 recyclerView 的滚动性能。
我正在使用 glide 加载我从 onBindViewHolder
中的 firebase 获取的图像,方法是调用 imageLoadGlide
方法,如下所示:
//Download image from firebase Storage and set gameImage("ImageView") image.
private void imageLoadGlide(DocumentSnapshot documentSnapshot, final QuestionsHolder questionsHolder) {
//for firebase storage
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
storageRef.child(documentSnapshot
.get("image").toString())
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//this part is loading image from url library
Glide
.with(context.getApplicationContext()) // pass Context
.load(uri)// pass the image url
.centerCrop() // optional scaletype
.crossFade() //optional - to enable image crossfading
.transform(new CircleTransform(context))//transfoms the imageView onto circle with the custon class CircleTransform
.into(questionsHolder.gameImage); // the ImageView to which the image is to be loaded
//stop the loading bar from spinning
questionsHolder.loadProgress.setVisibility(View.GONE);
}
});
}
下载工作正常,但滚动速度非常慢。
我不知道为什么会这样,因为我在上传图片之前压缩了图片,所以我认为这不是图片权重的问题。
图片压缩是这样的:
Bitmap bitmap = ((BitmapDrawable) questionImage.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);
关于为什么会发生这种情况以及如何避免这种情况的任何想法?
这是@Vadim Eksler 请求的onBindViewHolder
:
@Override
public void onBindViewHolder(@NonNull final QuestionsHolder holder, final int position) {
holder.gameImage.setImageBitmap(null);
setInfoForViews(holder, result.get(position));
imageLoadGlide(result.get(position), holder);
setOnClicksListners(holder, position);
setRankTextView(position, holder);
if (position == result.size() - 1 && !endOfDocs && next != null) {
loadMoreDocs(position);
}
}
此答案基于所有评论。
所以正如评论中提到的,我做错的是每次 onBindViewHolder
被调用时,我一次又一次地从 firebase 中提取图像 - 这导致 recyclerView 性能不佳。
我做了什么来修复它:
我使用 flyweight
设计模式仅在第一次从 firebase 加载图像,之后只需回收此图像以备下次使用 onBindViewHolder
将被调用。
首先我创建了一个地图作为全局变量:
private Map<String, Bitmap> flyweight = new HashMap<>();
之后,当第一次加载图像时,我会保存它以备后用 onBindViewHolder
再次调用时:
里面 onBindViewHolder
:
if (flyweight.get(result.get(position).get("image").toString()) == null) {
imageLoadGlide(result.get(position), holder); // load the image
} else {
//recycle the image that i already have
holder.gameImage.setImageBitmap(flyweight.get(result.get(position).get("image").toString()));
}
最后一件事是将我的图像添加到我成功拉取图像后创建的地图中:
flyweight.put(documentSnapshot.get("image").toString(), resource);
我有 recyclerview 并且在每一行中我都有一个我加载的图像 firebase storage。图像加载似乎影响了 recyclerView 的滚动性能。
我正在使用 glide 加载我从 onBindViewHolder
中的 firebase 获取的图像,方法是调用 imageLoadGlide
方法,如下所示:
//Download image from firebase Storage and set gameImage("ImageView") image.
private void imageLoadGlide(DocumentSnapshot documentSnapshot, final QuestionsHolder questionsHolder) {
//for firebase storage
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
storageRef.child(documentSnapshot
.get("image").toString())
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//this part is loading image from url library
Glide
.with(context.getApplicationContext()) // pass Context
.load(uri)// pass the image url
.centerCrop() // optional scaletype
.crossFade() //optional - to enable image crossfading
.transform(new CircleTransform(context))//transfoms the imageView onto circle with the custon class CircleTransform
.into(questionsHolder.gameImage); // the ImageView to which the image is to be loaded
//stop the loading bar from spinning
questionsHolder.loadProgress.setVisibility(View.GONE);
}
});
}
下载工作正常,但滚动速度非常慢。
我不知道为什么会这样,因为我在上传图片之前压缩了图片,所以我认为这不是图片权重的问题。
图片压缩是这样的:
Bitmap bitmap = ((BitmapDrawable) questionImage.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);
关于为什么会发生这种情况以及如何避免这种情况的任何想法?
这是@Vadim Eksler 请求的onBindViewHolder
:
@Override
public void onBindViewHolder(@NonNull final QuestionsHolder holder, final int position) {
holder.gameImage.setImageBitmap(null);
setInfoForViews(holder, result.get(position));
imageLoadGlide(result.get(position), holder);
setOnClicksListners(holder, position);
setRankTextView(position, holder);
if (position == result.size() - 1 && !endOfDocs && next != null) {
loadMoreDocs(position);
}
}
此答案基于所有评论。
所以正如评论中提到的,我做错的是每次 onBindViewHolder
被调用时,我一次又一次地从 firebase 中提取图像 - 这导致 recyclerView 性能不佳。
我做了什么来修复它:
我使用 flyweight
设计模式仅在第一次从 firebase 加载图像,之后只需回收此图像以备下次使用 onBindViewHolder
将被调用。
首先我创建了一个地图作为全局变量:
private Map<String, Bitmap> flyweight = new HashMap<>();
之后,当第一次加载图像时,我会保存它以备后用
onBindViewHolder
再次调用时:里面
onBindViewHolder
:if (flyweight.get(result.get(position).get("image").toString()) == null) { imageLoadGlide(result.get(position), holder); // load the image } else { //recycle the image that i already have holder.gameImage.setImageBitmap(flyweight.get(result.get(position).get("image").toString())); }
最后一件事是将我的图像添加到我成功拉取图像后创建的地图中:
flyweight.put(documentSnapshot.get("image").toString(), resource);