I have implemented a RecyclerView that contains mainly images which is loading in through Picasso. My problem is that as soon as I scroll down or up the view, the placeholde
I have encountered this issue recently, and yes you are right. Picasso is a good library for showing images from sdcard but it has some issues regarding cache if you are fetching images online that is why you see a place holder image while scrolling. I tried different things and the issue was not resolved.
There is an alternate library i.e. "AQuery" which is very good for fetching and caching images from network.
http://code.google.com/p/android-query/
The main advantages of AQuery/Android Query is that you can clear the cache, no lag while scrolling and quite effective for caching images and not showing place holder images while scrolling.
I resolved my issue by removing picaaso and using Aquery. Its just a one line replacement and you are done with your issue.
(new AQuery(mContext)).id(exploreViewHolder.getvProfilePic()).image(item.getUserProfilePicUrl().trim(), true, true, device_width, R.drawable.profile_background, aquery.getCachedImage(R.drawable.profile_background),0);
Besides you can easily shift from picasso to AQuery as there is no such thing which is available in picasso but not in AQuery and the syntax is almost the same. So I would recommend you to use AQuery, until this is fixed by picasso.
Setting recyclerView parameters as below solved my stutter problem :
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
i hope it helps someone else too.
The best answer of this question is do not use round image view just use transformation with simple image view because of round image view the application takes a lot of memory just use simple image view and set transformation with it. Use this transformation
Use fit()
.
Picasso.with(context)
.load(file)
.fit()
.centerCrop()
.into(imageView);
The fit()
actually resizes the image to fit into the imageView
's bounds. This doesn't load the full image and smoothens the scrolling.
Picasso automatically cache images in two levels:
They are bot initialized with defaults that suites most applications.
When the memory cache is getting too big the oldest used bitmap is removed from memory cache (which by default is 1/7 of the available heap space).
I think what's happening here is that you are close to the memory limit of the cache and thus images are decoded again every time you need them again.
See here: Android Picasso Configure LruCache Size
But I advice AGAINST increasing the memory cache size unless you really are re-sizing the images to the actual size you use..
I think the problem with your code is this:
.resize(deviceWidth, deviceWidth)
are you sure you really need an image of that size? What do you store in PrefUtils ? does it get updated when the device rotate? (landscape vs portrait)
If you need smaller images try to pass the resize the actual size of the image you are gonna use. If you don't know (computed at runtime with the layout) do with an approximation or write your code to obtain the actual size (I usually write custom classes extending ImageView for these stuff).
If you really need the images at that size just increase the cache size (see link above) and you should be good to go.
I mixed the answer from @ergunkocak and @Mangesh Ghotage, using this works great:
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
And this on every image:
Picasso.with(context)
.load(file)
.fit()
.into(imageView);
besides you could set Picasso to use a single instance like this:
Picasso.setSingletonInstance(picasso);
And finally enabling the cache indicators will give you clues on what's going wrong:
Picasso
.with(context)
.setIndicatorsEnabled(true);
More about Picasso