UIL, Picasso - Images in adapter always reload when stop scrolling - android

I have ListView with text and large image from internet. My image item has fit width and wrap_content height.
I tried to display image in background with UIL & Picasso. Both of them can work but the image always reloads when I stop scrolling, and it makes ListView flickering
It looks like this:
You can see that it reload downloaded and cached images when I stop scrolling (I scroll down and then scroll up).
How can I prevent this happen?
<ImageView android:id="#+id/imgFeed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"/>
// UIL
options = new DisplayImageOptions.Builder()
.showImageOnLoading(defaultImage)
.showImageOnFail(defaultImage)
.showImageForEmptyUri(defaultImage)
.resetViewBeforeLoading(false)
.cacheOnDisk(true).delayBeforeLoading(0)
.displayer(new FadeInBitmapDisplayer(200)).cacheInMemory(true).imageScaleType(ImageScaleType.EXACTLY_STRETCHED).build();
ImageAware imageAware = new ImageViewAware(viewHolder.imgFeed, false);
ImageLoader.getInstance().displayImage(item.getPhotoUrl(), imageAware, options);
// Picasso
Picasso.with(getContext())
.load(item.getPhotoUrl())
.placeholder(R.drawable.place_holder_big)
.resize(screenWidth, 0) //set max width
.into(viewHolder.imgFeed);
For UIL, I tried many ways in this issue but they don't work for me at all.
Update: seems I faced with memory cache issue like this question. But how can I fix this issue? Look at Facebook app, they did it very well. All images have different sizes with fit width, and very smooth scrolling without reloading images. How can they do that?

If you're wondering how Facebook did it, they actually released their image loading library (https://github.com/facebook/fresco)
Is it possible you are actually calling notifyDataSetChanged on the underlying ListView at that time? Also are you using hasStableIds()?
For UIL you could try using a WeakMemoryCache (refer to https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Useful-Info) as that'll theoretically allow you to make use of all available memory though it may cause a lot of extra GC calls.
For Picasso Taha's method looks like your best bet!

Maybe your memory cache size is small and Picasso tries to load images from disc cache. Please check here for deciding cache size. You can try to increase cache size of Picasso by:
Picasso p = new Picasso.Builder(context)
.memoryCache(new LruCache(cacheSize))
.build();
However in my opinion your app looks like having an endless feed. Which means your memory cache will be full at some time and you'll have to use disc cache. Retrieving data from the disc cache is slower compared to memory cache.

Related

How to check is Image is already cached in android mobile using Glide

I am storing my image and its reduced size image (blurred) in my Amazon Server, and store both path in database.
Now I want to know how to show blurred image first if original image is not cached and on clicking download it will download original Image. I am using Glide here...
I tried this
Glide.with(this)
.load(mainUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.thumbnail(Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE))
.centerCrop()
.into(imageView);
but problem is It automatically download original image in background.
I asked in Glide Github.
https://github.com/bumptech/glide/issues/2051
So add apply(RequestOptions.onlyRetrieveFromCache()) to your RequestOptions. You can register a listener and onFailed gets called when no image is in the cache.
Glide.with(TheActivity.this)
.load("http://sampleurl.com/sample.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(theImageView);
Your code will prevent Glide from downloading the GIF and will only show the GIF if it is already cached, which it sounds like you don't want.
Yes, the old image will eventually be removed. By default Glide uses an LRU cache, so when the cache is full, the least recently used image will be removed. You can easily customize the size of the cache to help this along if you want. See the Configuration wiki page for how to change the cache size.
Unfortunately there isn't any way to influence the contents of the cache directly. You cannot either remove an item explicitly, or force one to be kept. In practice with an appropriate disk cache size you usually don't need to worry about doing either. If you display your image often enough, it won't be evicted. If you try to cache additional items and run out of space in the cache, older items will be evicted automatically to make space.
If you want to show placeholder before image is loading then use code below:-
Glide.with(this)
.load(mainUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder("provide placeholder image here")
.thumbnail(Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE))
.centerCrop()
.into(imageView);

Picasso Taking time to load images

I'm using picasso to load images in my recycler view adaper but it is taking to much time to load image. Here is my call to load image with picasso.
Picasso.with(hostActivity).load("ImageUrl").fit().centerCrop().into(holder.ImageView);
If I do same thing with asynctask task, image loaded instantly.
Am I doing any thing wrong?
Thanks.
fit() needs to wait for the size of the ImageView to be determined before it can size the image to match, and the size can't be calculated until the end of the layout pass. You might get quicker results by using resize() if you are able to predict reasonable width and height values.
You might also want to look at the Glide library as it takes a different approach to caching that can be quicker than Picasso in some cases, for example instead of caching full size images it caches the resized ones. However, there are many pros and cons to both libraries; although the syntaxes are very similar, some things that work in Picasso will not work in Glide, and vice versa.

Picasso isn't loading scrolled images efficiently?

I am using a gridview that loads a bunch of images through picasso. I have implemented viewholders and I'm not sure what else I could do with the adapter or imageview to make it load better. I've isolated the issue to the image loading through an internet connection because the scrolling is fine when I load images locally.
The gridview scrolling is very buggy when using picasso and the scroll jumps around constantly when it shouldn't. What is the solution to this issue?
First of all I suggest you to use RecyclerView with GridLayoutManager or StaggeredGridLayoutManager. It must be more effective and view itself contain less bugs.
Next, use OkHttp with Picasso. It's more stable, powerful and consistent http client. And I think most important to you configure memory/file cache.
// Create a cache using an appropriate portion of the available RAM
Cache memoryCache = new LruCache(getApplicationContext());
// Use OkHttp as downloader
Downloader downloader = new OkHttpDownloader(getApplicationContext(),
PICASSO_DISK_CACHE_SIZE);
mPicasso = new Picasso.Builder(getApplicationContext())
.downloader(downloader).memoryCache(memoryCache).build();
Speed of loading also depend on network condition and image size.

ListView images preloading im ImageView without delay (using Picasso or other libs)

I have the problem with image loading in listview. I'm using Picasso to load pictures from network into my imageViews in each row. When I'm scrolling first time there always white background before image loaded in its place. Even if I scroll very slow or even stop scrolling before new item is showing, there still white background showing before the image is loaded. Even if these pictures wasn't taken from the network, but already from cache (yellow indicator). But when these pictures already in memory (green indicator) pictures don't loading each time when scrolling, they already loaded into imageView, so I don't have this white background (or it may appear on fast scrolling, but it's ok).
This how I use Picasso in my adapter:
Picasso.with(context).load(url).fit().centerCrop().into(imageView);
I know this is complicated topic and we can have OOM, but there should be some variants, as I can see it implemented in popular social networks, so I guess it possible.
P.S. fetch() doesn't helped me in this case, changing fit() with harcoded resize(200, 200) method also doesn't helped.
Please write your thoughts without silent minusing this post. Thanks!
Picasso.with("Pass Context") //
.load("Pass URL") //
.transform(new RoundedTransformation(5, 0))
.placeholder(R.drawable.*) //
.error(R.drawable.*) //
.fit() //
.tag(mcontext) //
.into("Your ImageView");

How to reduce image quality when using Universal Image Loader?

I'm using Universal Image Loader and I have to load 17 images from this page http://www.mangareader.net/detective-conan/898 then display it into ViewPager. However, images load very slow so I want to reduce the image quality and size for performance. What should I do to improve the speed?
Thanks.
I think it is not posible to download a scaled down version of image if the server does not supprt that feature. You can read more about it here.
One soltion to this is you can cache images when you run it for the first time. And next time check if the image is available in cache or not. if it is present in cache, get it from device else download it and cache it.
use BitmapConfigARGB_4444
DisplayImageOptions profilepicOptions = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.user_pic).cacheInMemory()
.cacheOnDisc().bitmapConfig(Bitmap.Config.ARGB_4444).build();

Categories

Resources