listView异步加载图片导致图片错位、闪烁、重复的问题的解决

 androidListView是android中重要的控件,几乎每一个项目都会用到。但是在使用中我们避免不

了会出现一些问题,包括一些滑动事件的处理,例如:ListView中嵌套scrollView,容易出现listView
展现数据不全的问题,还有就是listView中我们在加载图片的时候出现图片在加载中出现加载出来
的图片出现闪烁,在滑动listView中我们我们都会复用listView的缓存展示下一条的数据,其实我
们使用缓存也是为了提高listView的效率,减少内存的耗费,下面我就说说我在使用listView的时
候出现的问题及解决方案吧,一是作为笔记来保存,方便以后更深的理解和学习。二是让在学习
的小伙伴们不在出现这种问题,因为对于初学者来说(比如我)也是一种理解吧.
listView出现这种原因重要的就是图片异步加载的过程。首先listView在展示数据的时候,
没展示一条数据就会调用getView()一次,在我们进行下拉滑动的时候在新的数据展现出来的时
候我们都是在复用上一个item(也就是最顶部的item在不被可见的item),这时候的item还没
有被回收也就是里面的数据也没有回收旧被我们直接拿来使用了,这样会出现三个问题吧:一
,复用了上一个item,数据我们可以更新,但是图片可能我们更新不了,因为在加载图片的时
候我们就开启了线程去服务器请求图片,但是上一个item的图片还没有被回收,我们 在载的
图片还没有成功加载出来,这时候就复用了上一个item的图片;二,复用了上一个item同样
是图片没加载出来,但是由于内存的回收,图片被回收了,就出现了item上面的图片显示的
是是黑屏的渲染;三,同样是复用上一个item由于网络好加载图片很快,但是在我们快速滑
动的时候就出现了在不断复用item的时候就出现了图片加载错位了。针对以上的问题,
我在项目中做了一下事件,说了这么多其实可说说的全是废话吧,最关键的就是代码的实现。
其实真的来说要解决listView架子图片出现的问题,我们可以做如下的逻辑,明确一点
就是给listView设置一个标记,也就是setTag(),用url做唯一的标识进行判断。

//图片的请求服务器的工具类

public abstract class NetImageLoad {  
    private ImageView imageView;  
    private Handler handler = new Handler(){  
        public void handleMessage(android.os.Message msg) {  
            Bitmap bitmap = (Bitmap) msg.obj;  
            loadImage(imageView, bitmap);  
        };  
    };  

    public abstract void loadImage(ImageView imageView,Bitmap bitmap);  

    public void downloadImage(ImageView imageView,final String imgUrl){  
        this.imageView  =imageView;  
        new Thread(){  
            public void run() {  
                try {  
                    URL url = new URL(imgUrl);  
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
                    connection.setConnectTimeout(5000);  
                    connection.setReadTimeout(5000);  

                    InputStream is = connection.getInputStream();  
                    Bitmap bitmap = BitmapFactory.decodeStream(is);  

                    sleep(2000);  

                    Message message = new Message();  
                    message.obj = bitmap;  
                    handler.sendMessage(message);  

                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            };  
        }.start();  
    }  
}  
图片的加载处理
public class MainActivity extends Activity {  
    private ListView lv;  
    private List<String> urlList;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        lv = (ListView) findViewById(R.id.lv);  

        urlList = new ArrayList<String>();  

        for(int i = 0; i < 20; i++){  
            urlList.add(“图片存放的url地址”);//我使用的是Tomcat服务器  
        }  

        lv.setAdapter(new MyBaseAdapter());  
    }  

    class MyBaseAdapter extends BaseAdapter{  

        @Override  
        public int getCount() {  
            return urlList.size();  
        }  

        @Override  
        public Object getItem(int position) {  
            return urlList.get(position);  
        }  

        @Override  
        public long getItemId(int position) {  
            return position;  
        }  

        @Override  
        public View getView(final int position, View convertView, ViewGroup parent) {  
            ViewHolder viewHolder = null;  
            if(convertView == null){  
                viewHolder = new ViewHolder();  
                convertView = View.inflate(getApplicationContext(), 
                R.layout.list_item, null);  
                viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv);  
                convertView.setTag(viewHolder);  
            }else{  
                viewHolder = (ViewHolder) convertView.getTag();  
            }  

            viewHolder.imageView.setTag(urlList.get(position));  
            viewHolder.imageView.setImageResource(R.drawable.ic_launcher);  

            new NetImageLoad() {  
                @Override  
                public void loadImage(ImageView imageView, Bitmap bitmap) {  
                    if(imageView.getTag()!=null && imageView.getTag().equals(urlList.get(position))){  
                        imageView.setImageBitmap(bitmap);  
                    }  
                }  
            }.downloadImage(viewHolder.imageView,urlList.get(position));  

            return convertView;  
        }  
    }  

    class ViewHolder{  
        ImageView imageView;  
    }  
}  
  以上仅供参考,如有哪出有问题请给我留言,我及时更正,欢迎有大牛们指点。让我们能有更

深的提高,在这里谢谢那些为android开发提供资源的大牛们!!!!他们在前面的引路
给我们提高技术分享,让我们不断的学习,提升自己,谢谢他们,也欢迎伙伴们一起给我
分享,谢谢!!!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值