[Android] Perfectly solves the problem of network image skipping during ListView loading,
Why?
Let's first explain why the image jumps.
Use convertView to optimize each item in ListView. item reuse can effectively reduce memory usage and make ListView slide smoother. However, this may cause a problem. When the top item slides out of the screen, it will become the next item to slide in from the bottom. Each slide-in item needs to request the network to obtain the image.
When the first item slides out, it carries an image. Its ImageView points to a piece of memory. When it slides slowly out and slowly slides in from the bottom, the items at the bottom and the top (only half can be seen on the screen) still point
The same memory. The same image is loaded.
However, as long as the item at the bottom slides in, the system requests the network to obtain the image. If the image is successfully obtained from the bottom item, the original image will be overwritten.
When every item has such execution logic, the entire item will become messy and the image will flash.
Solution
There are two ways to solve this problem:
One is to check whether the ImageView is empty when the item is reused. If it is not empty (there are images ),
ViewHolder. imageview. setVisiable (View. GONE );
Then, this item will continue to request the network image. When the requested image is not blank (the request is successful and the setting is successful), the requested image is displayed in viewHolder. imageview. setVisiable (View. VISIABLE );
The following is a detailed process of the second approach.
Detailed Process
Layout file: Only one ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lv" android:layout_width="wrap_content" android:layout_height="wrap_content"/></RelativeLayout>
Layout of each item in ListView
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/item_iv" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:src="@drawable/ic_launcher"/></LinearLayout>
The key point is that the getView () method in MyAdapter has two key points.
Public MyAdapter (Context context, List <Info> data) {this. context = context; this. data = data ;}@ Overridepublic View getView (int position, View convertView, final ViewGroup parent) {final ViewHolder holder; if (convertView = null ){...} else {...} // obtain the object final Info = data in the set. get (position); // obtain the image URL final String img = info. getImgUrl (); <span style = "color: # ff0000;"> // key 1: Set a tag for each ImageView. The value is the image URL (ensure the uniqueness of the tag ). ). </Span> holder. iv. setTag (info. getImgUrl ());... bitmap bitmap =/* bitmap from network requests */<span style = "color: # ff0000;"> // key 2, get the tag value, compare with the URL of the scaled image in this item </span> String tag = (String) holder. iv. getTag (); <span style = "color: # ff0000;"> // If the imageview value is the same as the image address value, this image belongs to this ImageView and can be loaded. </Span> if (tag! = Null & tag. equals (info. getImg () {iv. setImageBitmap (bitmap);} return convertView;} class ViewHolder {TextView TV; ImageView iv ;}