在 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'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会被回收(重用),不会反复载入,结果肯定会更快。
我开发了一个聊天应用程序。它使用 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'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会被回收(重用),不会反复载入,结果肯定会更快。