Reputation: 2827
Currently, I'm developing a launcher app. The app has to load all icons into memory. In some older devices, when I load the app icons through the PackageManager
, the app crashes. That's why I'm currently loading icons in the onBindViewHolder(...)
method of RecyclerView
in a background thread:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// ...
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
handler.postAtFrontOfQueue(new Runnable() {
Drawable drawable = activity.getPackageManager().getApplicationIcon(app.name.toString());
@Override
public void run() {
viewHolder.appIconIv.setImageDrawable(drawable);
}
});
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
});
t.start();
// ...
}
But, the problem here is, the RecyclerView
stutters/lags while scrolling even though the icons are being loaded in the background. Plus, if I scroll to the bottom, all the icons are loaded into memory causing the app to crash on older devices (with less RAM). Besides, I don't think this is a good solution as it has to create a new thread for every single binding of the views. So, my question is, whether it is possible to know if the user has stopped scrolling (and only load icons then).
Any help regarding any of the issues I mentioned apart from the main question is really really appreciated and I'll be really grateful. [ specially all those performance/RAM issues :( ]
Thanks in advance. :D
Upvotes: 1
Views: 2916
Reputation: 5789
from the Blog:Image Loading with Picasso
Picasso.pauseTag()
RecyclerView.addOnScrollListener(new PicassoOnScrollListener(this));
Picasso.with(imageView.getContext().getApplicationContext()) .load(url) .tag(PicassoOnScrollListener.TAG) .into(imageView);
Upvotes: 1
Reputation: 499
First of all, I would heavily advise against ever using postAtFrontOfQueue for fear of pushing other things back. If you push things to the front, there's events that have the possibility of never getting executed resulting in strange behavior.
In an app I'm currently developing I'm waiting to load images with picasso until the user is done scrolling / flinging using this current implementation.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (Math.abs(dy) > SCROLL_THRESHOLD) {
mPicasso.pauseTag(FeedViewHolder.SEARCH_IMAGE_TAG);
} else {
mPicasso.resumeTag(FeedViewHolder.SEARCH_IMAGE_TAG);
}
}
});
You can use picasso to load drawable resources and set the tag like this
mPicasso.load(R.drawable.image_resource_name)
.fit()
.centerCrop()
.tag(SEARCH_IMAGE_TAG)
.into(imageView);
Upvotes: 1