Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView flickering when new items are added to it

I'm using ArrayAdapter to set data in ListView with endless scrolling functionality. There's an ImageView and two TextViews in a ListView's row. At first, I'm loading ListView with 10 items and on scroll down, I call the web service in setonscrolllistener to load next 10 items to the ListView. When new items are added to the Arraylist, I simply call adapter.notifysetdatachanged to tell adapter to refresh the ListView.

Now the problem is, whenever the new items get added to the ListView, the whole ListView refreshes and that causes the images in the ListView, which are already loaded, to flicker. Yes, I'm caching all the images in both disc and memory, and the code does the caching very smoothly.

I also tried adding data into adapter using this adapter.addall(myarraylist) but it didn't help. ImageViews are still flickering. I searched a lot about it on StackOverflow and found that you can't add and show more items in the ListView without refreshing the whole listView. I already know that but there must be some way to add new data to the ListView and not to refresh already loaded data.

I'm setting up the adapter like this.

public View getView(int position, View view, ViewGroup parent) 
      {

        int main = R.layout.layout;
        ViewHolder holder = null;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (view == null) {

            holder = new ViewHolder();
            view = inflater.inflate(main, null);
            holder.image = (ImageView) convertView.findViewById(R.id.imageview);

            ///More stuff

            view.setTag(holder);
        } else {
            holder = (ViewHolder)view.getTag();
        }

        // Loading ImageViews by Urls

        return view;
    }

Could anyone please shed some light on it?

like image 317
Avi Singh Avatar asked Oct 21 '22 08:10

Avi Singh


2 Answers

It seems that you're doing it the right way, so the problem might be from your imageLoader. It shouldn't set the image again on your imageview if the url is the same.

e.g. You can use the setTag (url) method on your imageView and test if the url has changed.

Hope this will help you.

like image 153
AMerle Avatar answered Nov 02 '22 10:11

AMerle


The solution is to not reload your image when it did not change.

In your adapters getView() do:

// schedule rendering:
final String path = ... (set path here);
if (holder.lastImageUrl == null || !holder.lastImageUrl.equals(path)
                || holder.headerImageView.getDrawable() == null) {
    // refresh image
    imageLoader.displayImage(imageUri, imageAware);
} else {
    // do nothing, image did not change and does not need to be updated
}

on success (add a ImageLoadingListener) you set holder.lastImageUrl = path, on fail and cancel you set holder.lastImageUrl to null so that it will reload next time.

like image 29
Frank Avatar answered Nov 02 '22 09:11

Frank