在 RecyclerView 中加载大量相同图像的有效方法

Efficient way to load large number of same image in ReyclerView

我开发了一个聊天应用程序。它使用 RecyclerView 来显示聊天信息。它与 Facebook Messenger 完全一样。

我的问题是,加载我正在聊天的用户的图像需要时间,并且当有大量聊天消息时会使应用变慢。

我正在使用 picasso 加载图像。

Picasso.get()
                    .load("https://domain/images/profile_picture/" + otherImage)
                    .networkPolicy(NetworkPolicy.OFFLINE)
                    .transform(new CircleTransform())
                    .into(imageView, new Callback() {
                        @Override
                        public void onSuccess() {

                        }

                        @Override
                        public void onError(Exception e) {

                            int placeHo;

                            if(otherGender.equals("female"))
                                placeHo = R.drawable.ic_female_color;
                            else
                                placeHo = R.drawable.ic_male_color;


                            Picasso.get()
                                    .load("https://domain/images/profile_picture/" + otherImage)
                                    .error(placeHo)
                                    .transform(new CircleTransform())
                                    .centerCrop(Gravity.TOP)
                                    .into(imageView, new Callback() {
                                        @Override
                                        public void onSuccess() {

                                        }

                                        @Override
                                        public void onError(Exception e) {
                                            Log.v("Picasso","Could not fetch image");
                                        }
                                    });
                        }
                    });

有什么有效的方法来显示图像吗?因为它显示相同的图像(用户个人资料图片)。

我认为您的 RecyclerView 滞后的原因只有一个。因为你的图像尺寸很大。

请注意,如果您的聊天图像约为 50-100dp,那么您应该使用相同分辨率的图像。也许您正在加载原始图像。

AFAIK 我在 Picasso 上使用 Glide,因为 Glide 优化了下载的图像,如 ImageView 大小。

Glide doc

Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.

您无需担心 Picasso 和 Glide 中的缓存。 Picasso 中默认启用缓存,因此如果再次查询同一图像,则会从缓存中选取它。

解决方案 1(使用 Piccaso)

Resize image 随心所欲。

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .resize(100, 100) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
    .into(imageViewResize);

方案二(使用Glide)

你不用担心任何事情,如果你使用 Glide 就可以了。

保持静态 或者您可以在初始化时设置它 不要每次都在 viewholder 上更改它

对不起我的英语和写作格式

RecyclerView.OnChildAttachStateChangeListener() 事件发出信号表明添加了 child 时,您必须推迟第一个图像检索过程。很明显,每个第一次可见的项目都会触发事件。推迟这样的事情最正确的方法是创建一个处理程序,然后 send/enqueue 一个 Handler.sendMessage(Message.obtain(..)) 每个可见的 objects) 项目。在处理程序中,您将收到该消息,您可以在那里执行 Picasso 操作。

然后你必须决定是一次加载其他(还不可见的项目)图像,还是仅在 Recycler 需要时才准备图片。

如果您在同一视图类型的所有视图中使用相同的图像,则在适配器的 onCreateViewHolder 方法中加载图像,而不是在 onBindViewHolder.

已经载入图片的同一个View会被回收(重用),不会反复载入,结果肯定会更快。