SoFunction
Updated on 2025-03-11

Analysis and solution for the asynchronous loading of ListView pictures in Android

Android ListView asynchronously loading pictures with misalignment, duplication, flicker analysis and solutions. For specific problem analysis and solutions, please see below.

When we use ListView to load pictures asynchronously, when we slide quickly or have poor network, we will have problems such as image misalignment, duplication, and flickering. In fact, these problems are summarized as a problem. We need to optimize these problems.

For example, there are 100 Items on ListView, and only 10 Items are displayed on a screen. We know that convertView in getView() is used to reuse View objects, because an Item corresponds to a View object, and the ImageView control is obtained by the View object through findViewById(). When we reuse the View object, the ImageView object is also reused. For example, if the View of the 11th Item multiplexes the first Item View object, the ImageView will be multiplexed at the same time. So when the image is not downloaded, the data displayed by the ImageView (11th Item) is the data of the multiplexed (1st Item).

1: Item image display is repeated

This display duplication means that the current row Item shows the picture of the previous row Item.

For example, if ListView slides to line 2, it will load a certain image asynchronously, but it is very slow to load. During the loading process, the ListView has already slided to line 14, and the image loading ends during the sliding process. Line 2 is no longer on the screen. According to the cache principle introduced above, the View object in line 2 may be multiplexed by line 14. What we see is that line 14 shows the picture that should belong to line 2, causing duplicate display.

2. The Item image display is incorrect

This display disorder means that a row of Items displays an image that does not belong to the row of Items.

The same reason as above.

3. The Item image display flashes

In another situation described above, if the picture on line 14 is loaded quickly, we see that the picture on line 14 first shows the picture on line 2, and immediately shows that the picture is covered and caused the flickering disorder.

Solution:

Through the above analysis, we know that the cause of the disorder is caused by asynchronous loading and the object being reused. If the getView can give the object an identifier every time, compare whether the identifier is consistent with the ID of the current row Item when the asynchronous loading is completed. If the identity is consistent, it will be displayed, otherwise it will not be processed.

principle: First, set a tag for ImageView. The url of the image is set in this tag. Then, when loading, get the url and the url in the position to be loaded. If it is different, load it. If the same means reuse the previous one and will not be loaded.

Android displays pictures in ListView (repeated confusing flickering problem)

1. Cause analysis

ListView item caching mechanism:

In order to make performance better, ListView will cache line item (View corresponding to a certain line).

ListView gets the item of each row through the adapter's getView function.

During sliding

a. If a line item has been slided out of the screen, if the item is not in the cache, put it into the cache, otherwise the cache will be updated;

b. Before obtaining the line item that slides into the screen, we will first determine whether there is an available item in the cache. If so, pass it to the adapter's getView as a convertView parameter.

In this way, the following getView writing method can make full use of cache and greatly improve the performance of ListView. Even if there are tens of thousands of rows of items, the maximum number of inflate is n.

n is the number of items that can display at most ListView rows in one screen.

@Override
public View getView ( int position , View convertView , ViewGroup parent ) {
  ViewHolder holder ;
  if ( convertView == null ) {
   convertView = inflater . inflate ( R . layout . list_item , null ) ;
   holder = new ViewHolder ( ) ;
   ……
   convertView . setTag ( holder ) ;
  } else {
   holder = ( ViewHolder ) convertView . getTag ( ) ;
  }
}

This improves performance, but it also causes other problems:

a. Line item image display repeat

This display duplication means that the current line item displays the picture of the previous line item.

For example, if ListView slides to line 2, it will load a certain image asynchronously, but it will load very slowly. During the loading process, the listView has already slided to line 14, and the image will be loaded in the process of sliding.

Line 2 is no longer on the screen. According to the cache principle introduced above, the view of line 2 may be reused by line 14, so what we see is that line 14 shows the picture that should belong to line 2.

Causes display duplication.

b. The line item image display is incorrect

This display disorder means that a row of items displays an image that does not belong to the row of items.

For example, if ListView slides to line 2, it will load a certain image asynchronously, but it will be very slow. During the loading process, the listView has already slided to line 14, and line 2 is no longer in the screen. According to the cache principle introduced above, the view on line 2 may be multiplexed by line 14, and line 14 displays the View on line 2. At this time, the previous image loading ends and will be displayed on line 14, causing confusion.

c. Line item image display flashes

In the case of b above, the picture on line 14 quickly loaded, so we saw that the picture on line 14 first showed the picture on line 2, and immediately showed that our picture was covered and caused the flickering disorder.

2. Solution

Through the above analysis, we know that the cause of the disorder is caused by asynchronous loading and object reuse. If the object can be given a identifier every time the getView can compare whether the identifier is consistent with the identifier of the current line item when the asynchronous loading is completed. If the identity is consistent, it will be displayed, otherwise it will not be processed.

Implementation code in andbase:

/**
   * Show this picture, solving the list problem.
   * List problem: During the sliding process, the imageView of the getView will be reused, resulting in the image being segmented
   * @param imageView View
   * @param url the url
   * @return
   */
  public void display( final ImageView imageView,String url) {
   if ((url)){
    if (noImage != null ){
     if (loadingView != null ){
      ();
      ();
     }
     (noImage);
    }
    return ;
   }
   //Set download items   final AbImageDownloadItem item = new AbImageDownloadItem();
   //Set the display size    = width;
    = height;
   //Set to zoom    = type;
    = url;
   final String cacheKey = AbImageCache
   .getCacheKey(, , , );
    = (cacheKey);
   //if(D) (TAG, "Getted in cache"+cacheKey+":"+);   //Set the mark   (url);
   if ( == null ){
    //Show loading first    if (loadingView!= null ){
     ();
     ();
    } else if (loadingImage != null ){
     (loadingImage);
    }
    //Update the interface after downloading    ( new AbImageDownloadListener() {
     @Override
     public void update(Bitmap bitmap, String imageUrl) {
      //The loading picture is not set, and the hidden View is set      if (loadingView != null && (())){
       ();
       ();
      }
      //You must judge that the URL of this imageView has changed. If there is no change, set.      //Cancel if there is any change, solve the problem of reusing the View of the list.      if(bitmap!=null&& (())){
       if (D) (TAG, "Picture download, settings:" +imageUrl);
       (bitmap);
      } else {
       if (errorImage != null && (())){
        (errorImage);
       }
      }
     }
    });
    if (D) (TAG, "Picture download, execute:" +url);
    (item);
   } else {
    if (loadingView != null ){
     ();
     ();
    }
    ();
   }
  }

The above content is the analysis and solution of the misalignment, duplication and flickering of the asynchronous loading of ListView in Android. I hope it will be helpful to everyone's future work and study.