我有recyclerview,并且在每一行中都有一张我用firebase storage加载的图像。似乎图像加载正在影响recyclerView的滚动性能。
我正在使用滑行通过调用onBindViewHolder
这样的方法在imageLoadGlide
内从Firebase加载图像:
//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);
关于为什么发生这种情况以及如何避免这种情况的任何想法?
这里是onBindViewHolder
,用于@Vadim Eksler的请求:
@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);
}
}
答案 0 :(得分:0)
此答案基于所有评论。
因此,正如评论中提到的,我做错了是,每次调用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);