如何正确地将 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);