I have a very frustrating problem and I don't have an idea what is wrong. I build simple XML which contains only GridView. This gridview should show images (ImageView) downloaded from specific urls which I retreive with my code.
So the idea of this APP is only to download images from URLS and show those images in GridView. First I must say that I'm using Universal Image Loader library. First please look at my getView code:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv;
if(convertView == null) {
iv = new ImageView(MyActivity.this);
iv.setLayoutParams(new GridView.LayoutParams(size,size));
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
Log.d("APP", "convertView is NULL");
}
else {
iv = (ImageView) convertView;
Log.d("APP", "convertView is NOT null");
}
loader.displayImage(URLS.get(position), iv);
return iv;
}
PROBLEM:
Code above works, and it shows images in GridView. But when I scroll down, I see that:
- All images were downloaded (Even those images who are not visible )
- When i scroll back up I see that image which was in place 0, is in place 1 and it has been downloaded again. When I scroll back down, images switched positions again. Scrolling back up, I see again images are switching places again ( and downloading again). This goes infinite.
HOW I SOLVED THIS PROBLEM:
I solved this problem by NOT checking if convertView variable is null. Actually I ommited if/else clause.
I used cache in memory = true. So downloading stops and images are in place for ever.
So why I'm asking for help? Mainly because i know that i should not ommit if/else clause for performance reasons. I don't want to mess with users memory and I would like to bring them fast and reliable user experience. Also i would like to know what could be wrong.
Thank you for help. Much appriciated.
Loader needed some time to load picure in ImageView
. Because you reuse view for different images you can see a previous image in the view while new image is loading. You can set resetViewBeforeLoading(true)
in DisplayImageOptions
for avoid this effect.
Also you can use disk cache to avoid downloading images every time from the network. Also limit size of memory cache and set other settings, but I think memory cache is useful, it improves user experience.
And don't forget to use setOnScrollListener(new PauseOnScrollListener(loader, true, true))
to avoid lags on scrolling.
GridView recycles list items for performance purposes. So when you are scrolling, the list items are getting recycled in different places and then your code is re-populating them. Sometimes this lags for images.
I'd recommend using a library that handles this sort of thing like Picasso.
I was having the exactly same problem as you, and didn't want to disable convertView checking either. My solution was to increase the memory cache size in ImageLoaderConfiguration.
Before, i used to use it like this:
.memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
So I changed it to:
.memoryCache(new UsingFreqLimitedMemoryCache(10 * 1024 * 1024))
I don't know if 10*1024*1024 is too much or it will cause any problems, but it seems to have fixed the problem to me and i haven't had any problems until now.
来源:https://stackoverflow.com/questions/18421191/imageviews-changed-positions-when-scrolling-in-gridview