完美解决ListView加载网络图片乱跳问题

先说一下为什么会出现图片乱跳。

使用convertView对ListView的每个item优化,item的复用可以有效降低内存的占用,使ListView滑动更为流畅。但会带来一个问题,当最顶部的item滑出屏幕时,会变成下一个从底部将要滑进来的item。每次滑进来的item都要去请求网络获得图片。

第一个item滑出去时,是带着图片的。其ImageView指向了一块内存。当其慢慢滑出,从底部慢慢滑进时,底部的item与顶部(只有一半在屏幕里能看到了)的还是指向

同一块内存。加载的了同一张图片。

但是底部的item只要一滑进来,就开始请求网络,要获取图片了。当底部item获取图片成功会将原有的图片覆盖。

当每个item都是这样的执行逻辑,整个item就会变得很乱,图片乱闪。

 

如何解决

解决这个问题有两个思路:

一个是为在item复用时,检查ImageView上是否为空,如果不为空(有图片),则

viewHolder.imageview.setVisiable(View.GONE);

然后这个item会继续执行请求网络图片,当请求下来的图片不为空(请求成功,并且设置成功),此时在viewHolder.imageview.setVisiable(View.VISIABLE);

 

下面是第二种思路的详细过程。

详细过程

布局文件:只有一个ListView

 

?
1
2
3
4
5
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
 
    <listview android:id="@+id/lv" android:layout_height="wrap_content" android:layout_width="wrap_content">
 
</listview></relativelayout>

ListView每个item布局

 

 

?
1
2
3
4
5
6
<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
     
    <imageview android:id="@+id/item_iv" android:layout_gravity="center_horizontal" android:layout_height="100dp" android:layout_width="100dp" android:src="@drawable/ic_launcher">
 
</imageview></linearlayout>

重点来了,MyAdapter中getView()方法,有两个重点。

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public MyAdapter(Context context,List<info> data){
    this.context = context;
    this.data = data;
}
 
@Override
    public View getView(int position, View convertView, final ViewGroup parent) {
        final ViewHolder holder;
        if(convertView ==null){
            ...
        }else{
            ...
        }
        //获得集合中实体类对象
        final Info info = data.get(position);
        //获得图片网址
        final String img = info.getImgUrl();
         
        <span style="color:#ff0000;">//重点1,为每个ImageView设置一个tag,值为图片网址(保证tag的唯一性)。</span>
        holder.iv.setTag(info.getImgUrl());
        ...
         
        Bitmap bitmap =/*网络请求来的bitmap*/
 
        <span style="color:#ff0000;">//重点2,获得tag的值,与该item中缩放图片的网址进行比较</span>
        String tag = (String) holder.iv.getTag();
        <span style="color:#ff0000;">//如果这个imageview的值,和他应该放的图片的地址值一样,说明这个图片是属于这个ImageView的,可以加载。</span>   
        if(tag!=null&&tag.equals(info.getImg())){
            iv.setImageBitmap(bitmap);
        }
 
        return convertView;
    }
     
    class ViewHolder{
        TextView tv;
        ImageView iv;
         
    }</info>
展开阅读全文

没有更多推荐了,返回首页