Solution for duplicate image display disorder during AndroidListview Sliding Process,
This section mainly analyzes the causes and solutions of duplicate, disordered, and flickering image display caused by Listview scrolling in Android, and follows up with the Listview cache mechanism by the way.
1. Cause Analysis Listview item caching mechanism: in order to improve performance, Listview caches the row item (view corresponding to a row ). Listview obtains the items of each row through the getview function of the adapter. During the Sliding Process, a. If a row of items has already drawn a screen, if the item is not in the cache, put it into the cache; otherwise, update the cache; b. before obtaining the row item that slides into the screen, the system first checks whether there are available items in the cache. If yes, it is passed as the convertview parameter to the getview of the adapter. In this case, the following getview method can make full use of the cache to greatly improve the performance of listview. Even if there are tens of thousands of rows of items, the maximum number of inflate is n, and n is a screen, the maximum number of items in the listview row is displayed. @ Overridepublic 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 () ;}} improves performance, but also causes some problems. Original article: The timer is no longer on the screen. According to the cache principle described above, the view on the second line may be taken by row 14th, in this way, we can see that 14 rows show images that should belong to the second row, resulting in duplicates. B. Row item display disorder this display disorder means that a row item shows an image that does not belong to this row item. For example, if the listview slides to the second row to asynchronously load an image, but the loading is slow, the listview slides to 14 rows during the loading process, and the second row is no longer in the screen. According to the cache principle described above, the view in the second row may be reused by 14th rows. The view in the second row is displayed in the second row. When the previous image loading ends, it will be displayed in 14th rows, causing confusion. C. The row item is shown as B, and the row 14 is quickly loaded. So we can see that the row 14th first shows the image of the second line, I immediately showed the flickering disorder caused by overwriting my images. 2. Solution: Through the above analysis, we know that the cause of confusion is caused by asynchronous loading and Object reuse. If each getview operation can provide an identifier for an object, when asynchronous loading is complete, compare whether the identifiers are consistent with those of the current item. If they are consistent, display them. Otherwise, do not process them. Add @ Overridepublic 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 ();}..... Imageview. setTag (imageurl); if (! Cache. icon_catch.get (imageurl, imageview) {imageview. setimageDrawable (null );}}
The setTag indicates that the identifier is set to facilitate the following comparison.
| 1 |
If (! Cache. ICON_CACHE. get (imageUrl, imageView )) |
Cache. ICON_CACHE is an ImageCache instance. It indicates that if it is not in the cache, drawable is set to null (of course you can set it to your own default Resource) to prevent the image of an item in a previous row from being displayed, solved. duplicate row item image display.
In the onImageLoaded function of OnImageCallbackListener of ImageCache, add
Java
| 1234567891011 |
Public void onImageLoaded (String imageUrl, Drawable imageDrawable, View view, booleanisInCache) {// can be another view child, like textView and so on if (view! = Null & imageDrawable! = Null) {ImageView imageView = (ImageView) view; // add tag judge, avoid listView cache and so on String imageUrlTag = (String) imageView. getTag (); if (ObjectUtils. isEquals (imageUrlTag, imageUrl) {imageView. setImageDrawable (imageDrawable );}}}; |
Use String imageUrlTag = (String) imageView above. getTag (); get the previously set tag, and then compare it with the current url. If it is equal, it will be displayed, solving B. the row item image is displayed in disorder, c. there are two problems with line item Image Display disorder. Here, ObjectUtils is visible to ObjectUtils @ Github.
Other asynchronous loading processes work in a similar way.