【问题标题】:Loading Images from Firebase Storage in Recycler Shows Images changing在 Recycler 中从 Firebase 存储加载图像显示图像正在更改
【发布时间】:2018-10-10 01:38:45
【问题描述】:

我正在使用 recyclerview 从 fire base 存储中加载我的图像,但是当我加载图像 A 时,可以说图像 A 滚动到该图像视图被回收并将用于显示图像 B 的位置,我仍然可以在它之前短暂地看到图像 A更改图像 B,

有没有办法避免这种情况?

这是我的适配器的代码

public class ComicRecyclerAdapter extends RecyclerView.Adapter<ComicRecyclerAdapter.ComicHolder> {


public ComicRecyclerAdapter(ArrayList<Comic> comicsInSection) {
    this.mComicsInSection = comicsInSection;
}

@Override
public ComicHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //Bind the Comic object to the ComicHolder
    View comicView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_grid_comic, parent, false);

    return new ComicRecyclerAdapter.ComicHolder(comicView);
}

@Override
public void onBindViewHolder(final ComicHolder holder, int position) {
    Comic currentComic = mComicsInSection.get(position);

    storageRef.child(currentComic.getTitle() + "/"
            + currentComic.getCoverImage()).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            //Load image using Picasso
            Picasso.get()
                    .load(uri)
                    .fit()
                    .into(holder.coverImage, new Callback() {
                        @Override
                        public void onSuccess() {
                            //image loaded stop loading icon
                            holder.loadingComic.setVisibility(View.GONE);
                        }

                        @Override
                        public void onError(Exception e) {

                        }
                    });
        }
    });
}

@Override
public int getItemCount() {
    return (null != mComicsInSection ? mComicsInSection.size() : 0);
}

public void addAll(ArrayList<Comic> comicsToAdd) {
    mComicsInSection.addAll(comicsToAdd);
    notifyDataSetChanged();
}

public void clear() {
    mComicsInSection.clear();
    notifyDataSetChanged();
}

static class ComicHolder extends RecyclerView.ViewHolder {
    //Find all views needed
    @BindView(R.id.comic_cover_image)
    ImageView coverImage;
    @BindView(R.id.loading_comic)
    ProgressBar loadingComic;

    public ComicHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

}

【问题讨论】:

  • 嗨@Reshaud,你为什么把这个图片url下载代码放在回收站视图中?
  • 嗨@RishabhSaxena 我把它放在那里主要是为了让它显示在回收器视图中,因为我的班级只存储图像名称“imageA.jpg”的最后一部分,我应该做一个更好的方法吗这个?
  • 我建议您先获取图像 URL 列表,然后转到适配器并简单地使用 Picasso 加载它。现在,当回收器视图滚动时会发生什么情况,那么您可能会首先获得第 3 位 URL 而不是第 1 位,这可能会导致您意想不到的结果。
  • 嗨@RishabhSaxena 会试试这个并告诉你进展如何
  • 嗨@RishabhSaxena,非常感谢!!

标签: android firebase android-recyclerview firebase-storage


【解决方案1】:

我建议您先获取图像 URL 列表,然后转到适配器并简单地使用 Picasso 加载它。现在发生了什么,当回收器视图滚动时,您可能会首先获得第 3 位 URL 而不是第 1 位,这可能会导致您意想不到的结果。

【讨论】:

    【解决方案2】:

    如果你使用Glide Library,你可以创建GlideModule类并使用Firebase Ui Storage依赖。感谢 Firebase Ui 存储库,您不必使用对大数据太慢的 getDownloadUrl() 方法,并且当您在适配器类的 onBindViewHolder 方法中使用时,所有图像都会再次重新加载/随机播放再次。

    在您的应用程序 gradle 中添加这些依赖项:

    // Find the latest Glide releases
    implementation 'com.github.bumptech.glide:glide:4.x'
    // If you're using Kotlin (and therefore, kapt), use kapt instead of annotationProcessor
    annotationProcessor 'com.github.bumptech.glide:compiler:4.x'
    

    为 GlideModule 创建一个新类:

    @GlideModule
    public class MyAppGlideModule extends AppGlideModule {
    
        @Override
        public void registerComponents(Context context, Glide glide, Registry registry) {
            // Register FirebaseImageLoader to handle StorageReference
            registry.append(StorageReference.class, InputStream.class,
                    new FirebaseImageLoader.Factory());
        }
    }
    

    直接在您的适配器类中使用 Firebase 图像参考链接:

      // top level variable
         FirebaseStorage storage = FirebaseStorage.getInstance();
        
         @Override
            public void onBindViewHolder(@NonNull final BuildingAdapter.BuildingViewHolder holder,
                                         int position) {
     // create imagePath for Glide library. ImagePath = server url + image name
         StorageReference storageRef = storage.getReferenceFromUrl(FIREBASE_STORAGE_MAIN_LINK + "/"+ data.get(position).getImageName());
        
                Glide.with(context)
                        .load(storageRef)
                        .apply(new RequestOptions()
                                .placeholder(R.drawable.image_not_found)
                                .fitCenter())
                        .into(holder.im);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-22
      • 2017-01-22
      • 2020-06-06
      • 2020-06-14
      • 2020-04-20
      • 2017-12-01
      • 2018-01-16
      相关资源
      最近更新 更多