如何将Firebase存储映像正确下载到RecycelrView

时间:2019-05-02 09:16:05

标签: android firebase android-recyclerview firebase-storage android-glide

我有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);
    }
}

1 个答案:

答案 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);