Android 如何将firebase存储映像正确下载到RecycelView中

Android 如何将firebase存储映像正确下载到RecycelView中,android,firebase,android-recyclerview,firebase-storage,android-glide,Android,Firebase,Android Recyclerview,Firebase Storage,Android Glide,我有recyclerview,每一行我都有一个我加载的图像。图像加载似乎影响了recyclerView的滚动性能 我正在使用glide加载我从firebase内部onBindViewHolder获取的图像,方法如下: //Download image from firebase Storage and set gameImage("ImageView") image. private void imageLoadGlide(DocumentSnapshot documentSnapshot, f

我有recyclerview,每一行我都有一个我加载的图像。图像加载似乎影响了recyclerView的滚动性能

我正在使用glide加载我从firebase内部
onBindViewHolder
获取的图像,方法如下:

//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);
        }
    });
}
关于为什么会发生这种情况,以及我如何避免这种情况,有什么想法吗

这里是@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 flyweight=new-HashMap()

  • 之后,当从第一次加载图像时,我将保存它,以备以后再次调用
    onBindViewHolder
    时使用:

    在BindViewHolder内部

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

此答案基于所有评论。


因此,正如评论中提到的,我做错了的是,每次调用
onBindViewHolder
时,我都会一次又一次地从firebase中提取图像-这导致recyclerView性能不佳

我做了什么来修复它: 我已经使用了
flyweight
设计模式首次从firebase加载图像,之后只需在下次调用
onBindViewHolder
时循环使用此图像

  • 首先,我创建了一个映射作为全局变量:

    private-Map flyweight=new-HashMap()

  • 之后,当从第一次加载图像时,我将保存它,以备以后再次调用
    onBindViewHolder
    时使用:

    在BindViewHolder内部

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

你能发布你的
onBindViewHolder
方法吗?@VadimEksler刚刚在每次调用
onBindViewHolder
时更新了问题,你去firebase运行glide。我认为您需要将图像URI保存到对象中,并进行检查
if(result.get(position.getUri()==null){imageLoadGlide(result.get(position),holder);}否则{make just glide.load…}
。您还需要删除此
setImageBitmap(null)并打开滑动缓存。首先,对于圆形图像,请使用circleImage库;其次,请尝试获取较小的图像大小;第三,在滑动中使用缩略图。这将非常适合你。我已经根据这里的所有评论添加了一个答案@Vadim Eksler这是一个很好的建议@Blacklind我发现CircleImageLibrary存在一些问题,所以我不想使用它,降低图像大小是一个很好的建议,我使用的是非常小的图像,我来看看tuimbnail。你能发布你的
onBindViewHolder
方法吗?@VadimEksler刚刚更新了问题,每次调用
onBindViewHolder
时,你都去firebase运行glide。我认为您需要将图像URI保存到对象中,并进行检查
if(result.get(position.getUri()==null){imageLoadGlide(result.get(position),holder);}否则{make just glide.load…}
。您还需要删除此
setImageBitmap(null)并打开滑动缓存。首先,对于圆形图像,请使用circleImage库;其次,请尝试获取较小的图像大小;第三,在滑动中使用缩略图。这将非常适合你。我已经根据这里的所有评论添加了一个答案@Vadim Eksler这是一个很好的建议@Blacklind我发现CircleImageLibrary存在一些问题,所以我不想使用它,降低图像的大小是一个很好的建议,我使用的是非常小的图像,我会看看tuimbnail。