解决ListView异步加载网络图片的各种问题(二)

简介: MainActivity如下: package lee.listviewimage; import java.util.ArrayList; import java.

MainActivity如下:

package lee.listviewimage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lee.listviewimage.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
//解决的问题:
//1 ListView异步加载网络图片
//2 ListView滑动时,图片错位
public class MainActivity extends Activity {
    ListView listView;
    List<Map<String, Object>> arrayList; 
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.main);
        listView = (ListView) findViewById(R.id.listView);
        arrayList = new ArrayList<Map<String, Object>>();

        Map<String, Object> tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title111");
        tempHashMap.put("info", "111111");
        tempHashMap.put("img", "http://tb.himg.baidu.com/sys/portrait/item/d71e5a30323837797979d300");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://img.baidu.com/img/post-jg.gif");
        arrayList.add(tempHashMap);
      
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh5.ggpht.com/_mrb7w4gF8Ds/TCpetKSqM1I/AAAAAAAAD2c/Qef6Gsqf12Y/s144-c/_DSC4374%20copy.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh5.ggpht.com/_Z6tbBnE-swM/TB0CryLkiLI/AAAAAAAAVSo/n6B78hsDUz4/s144-c/_DSC3454.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh3.ggpht.com/_GEnSvSHk4iE/TDSfmyCfn0I/AAAAAAAAF8Y/cqmhEoxbwys/s144-c/_MG_3675.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh6.ggpht.com/_Nsxc889y6hY/TBp7jfx-cgI/AAAAAAAAHAg/Rr7jX44r2Gc/s144-c/IMGP9775a.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh3.ggpht.com/_lLj6go_T1CQ/TCD8PW09KBI/AAAAAAAAQdc/AqmOJ7eg5ig/s144-c/Juvenile%20Gannet%20despute.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh6.ggpht.com/_ZN5zQnkI67I/TCFFZaJHDnI/AAAAAAAABVk/YoUbDQHJRdo/s144-c/P9250508.JPG");
        arrayList.add(tempHashMap);

        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://lh6.ggpht.com/_lnDTHoDrJ_Y/TBvKsJ9qHtI/AAAAAAAAG6g/Zll2zGvrm9c/s144-c/000007.JPG");
        arrayList.add(tempHashMap);
        
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://info-database.csdn.net/Upload/2012-10-08/zazhi-210-90-1008.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://images.csdn.net/20121119/20111211223655841.jpg");
        arrayList.add(tempHashMap);
		
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://csdnimg.cn/www/images/pic_foot_report110.png");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://images.csdn.net/20121119/20120619174604972.jpg");
        arrayList.add(tempHashMap);
        

        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://images.csdn.net/20121018/zazhi-68-78-1018.jpg");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://csdnimg.cn/www/images/pic_foot_report.png");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://www.iteye.com/upload/logo/blog_wiki/711943/3a7f0290-47e6-3d62-8845-49735bc19a96.jpg?1343020143");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://www.iteye.com/upload/logo/user/731519/c828deb2-5350-3fc7-83e7-b0eaa047d804-thumb.jpg?1346417059");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://www.iteye.com/upload/logo/user/766328/b7d5f98d-f682-3d54-b697-6b9bacbcd534-thumb.jpg?1352965075");
        arrayList.add(tempHashMap);
        
        tempHashMap = new HashMap<String, Object>();
        tempHashMap.put("title", "title222");
        tempHashMap.put("info", "222222");
        tempHashMap.put("img", "http://www.iteye.com/upload/logo/user/40888/c82ef195-e561-3ac1-8714-a905052eae6d-thumb.jpg?1236834197");
        arrayList.add(tempHashMap);
        

        //利用此binder对象为ListViewItem中的小各个小控件绑定数据.此例子中未操作
        //注意:setViewValue方法的返回值很重要
        //即:bound=binder.setViewValue(everyViewOfThisHolder, data, textRepresentation);
        //一般的思路:
        //若此处返回false表示在TestSimpleAdapter里面继续对每个item进行数据的绑定.
        //若此处返回true表示在TestSimpleAdapter里面需要再对每个item进行数据的绑定
        //当然具体情况还是视具体的业务逻辑而定
        SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {	
			@Override
			public boolean setViewValue(View view, Object data,String textRepresentation) {
				return false;
			}
		};
		 //listView原理http://www.xuanyusong.com/archives/1252
		  TestSimpleAdapter adapter = new TestSimpleAdapter(
		    		this,arrayList, R.layout.listviewitem, 
		    		new String[] {"title", "info", "img" }, 
		    		new int[] {R.id.title, R.id.info,R.id.imageView
		        },binder);
		//为此adapter设置ViewBinder
        adapter.setViewBinder(binder);
        listView.setAdapter(adapter);
	}    
}


自定义SimpleAdapter如下:

package lee.listviewimage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class TestSimpleAdapter extends SimpleAdapter {
    private AsyncImageLoader imageLoader = new AsyncImageLoader();
    //按照ListViewItem在ListView中的位置保存了此ListViewItem对应的View
    private Map<Integer, View> allItemsViewHashMap = new HashMap<Integer, View>();
    private LayoutInflater mInflater;
    private ViewBinder mViewBinder;
    private List<? extends Map<String, ?>> mData;
    private int mResource;			
    private String[] mFrom;				
    private int[] mTo;	
    
    //构造方法
    public TestSimpleAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to,ViewBinder binder) {
        super(context, data, resource, from, to);
        mData = data;
        mResource = resource;
        mFrom = from;
        mTo = to;
        mViewBinder=binder;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    	
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
          return createViewFromResource(position, convertView, parent, mResource);
    }

 
    private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
        View everyItemView = this.allItemsViewHashMap.get(position);            
        if (everyItemView == null) {
            everyItemView = mInflater.inflate(resource, null);
            final int[] to = mTo;
            final int count = to.length;
            final View[] allPartsOfThisItem = new View[count];
            //将此Item中的所有子View存放在allPartsOfThisItem中
            for (int i = 0; i < count; i++) {
                allPartsOfThisItem[i] = everyItemView.findViewById(to[i]);
            }
            //给此itemView设置Tag!!!
            everyItemView.setTag(allPartsOfThisItem);
            //调用bindView.注意查看SimpleAdapter源码中也有这个方法.名字都一样
            //上一句setTag了,那么按照以往BaseAdapter的做法
            //后面就该为此item中的各个小控件赋值了,即在bindView中进行
            bindView(position, everyItemView);
            //将此Item对应的View保存到HashMap中
            allItemsViewHashMap.put(position, everyItemView);
        }
        return everyItemView;
    }
    
    //每个Item都会调用此方法
    //ViewBinder相当于设定了绑定规则
    //类似于BaseAdapter中getView中后半部分为此Item各控件赋值的处理
    @SuppressWarnings("unchecked")
    private void bindView(int position, View view) {
    	//取出listView中对应于此item中的数据(对应一个HashMap)
        final Map everyHashMapForAItem = mData.get(position);
        if (everyHashMapForAItem == null) {
            return;
        }  
        final ViewBinder binder = mViewBinder;
        //bindView方法的第二参数,即为ListView的每个item
        //得到ListView的每个item的Tag
        //并将里面获取的所有小组件保存至allMinViews中
        final View[] allMinViews = (View[]) view.getTag();
        final String[] from = mFrom;
        final int[] to = mTo;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View everyViewOfThisHolder = allMinViews[i];
            if (everyViewOfThisHolder != null) {
            	//以from[i]为键从HashMap中取出对应的值  
                final Object data = everyHashMapForAItem.get(from[i]);
                String textRepresentation = null;

                if (data == null) {
                	textRepresentation = "";
                } else {
                	//参考binder.setViewValue方法的文档.可知textRepresentation
                	//一般为data.toString
                	textRepresentation = data.toString();
                }

                boolean bound = false;
                if (binder != null) {	
                	//重要参考资料:
                	//http://www.cnblogs.com/angeldevil/archive/2012/04/05/2432615.html
                	//http://www.cnblogs.com/over140/archive/2010/12/15/1906303.html
                	//该方法的作用:判断在MainActivity中binder的方法setViewValue的返回值
                    bound = binder.setViewValue(everyViewOfThisHolder, data, textRepresentation);
                }

                if (!bound) {
                    if (everyViewOfThisHolder instanceof Checkable) {
                        if (data instanceof Boolean) {
                            ((Checkable) everyViewOfThisHolder).setChecked((Boolean) data);
                        } else {
                            throw new IllegalStateException(everyViewOfThisHolder.getClass().getName()+
                            		" should be bound to a Boolean, not a "+ data.getClass());
                        }
                    } else if (everyViewOfThisHolder instanceof TextView) {
                    	//setViewText 是simpleAdapter的方法
                        setViewText((TextView) everyViewOfThisHolder, textRepresentation);
                    } else if (everyViewOfThisHolder instanceof ImageView) {
                        if (data instanceof Integer) {
                        	//setViewImage是simpleAdapter的方法
                        	//调用setImageToImageView1也一样
                            setViewImage((ImageView) everyViewOfThisHolder, (Integer) data);
                        } else {
//                        	if (position==1) {
//								v.setVisibility(android.view.View.GONE);
//							} else {
//								setViewImage((ImageView) v, urlText);
//							}
                        	setImageToImageView2((ImageView) everyViewOfThisHolder, textRepresentation);
                        }
                    } else {
                        throw new IllegalStateException(everyViewOfThisHolder.getClass().getName()+ 
                        		" is not a "+ " view that can be bounds by this SimpleAdapter");
                    }
                }
            }
        }
    }

     //ImageView及图片的资源id
     public void setImageToImageView1(ImageView v, int value) {
         v.setImageResource(value);
     }
    //ImageView及图片的URL
     public void setImageToImageView2(final ImageView iamgeView, String url) {
         imageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() {
             public void imageLoaded(Drawable imageDrawable, String imageUrl) {
                 if(imageDrawable!=null && imageDrawable.getIntrinsicWidth()>0 ) {
                	 iamgeView.setImageDrawable(imageDrawable);
                 }
             }
         });
     }

 } 


异步加载网络图片,方法如下:

package lee.listviewimage;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
public class AsyncImageLoader {
    private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
    public Drawable loadDrawable(final String imageUrl,final ImageCallback callback) {
    	if (imageCache.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            if (softReference.get() != null) {
                return softReference.get();
            }
        }
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                callback.imageLoaded((Drawable) msg.obj, imageUrl);
            }
        };
     
        new Thread() {
            public void run() {
            	//从网络上获取图片
                Drawable drawable = loadImageFromUrl(imageUrl);
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                handler.sendMessage(handler.obtainMessage(0, drawable));
            };
        }.start();
        
        return null;
    }

    protected Drawable loadImageFromUrl(String imageUrl) {
        try {
            return Drawable.createFromStream(new URL(imageUrl).openStream(),"src");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //定义一个回调接口
    public interface ImageCallback {
        public void imageLoaded(Drawable imageDrawable, String imageUrl);
    }
    
}


listviewitem.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="50dip">

    <ImageView 
        android:id="@+id/imageView"
        android:layout_width="50dip"
        android:layout_height="50dip" 
        android:scaleType="fitXY" 
        android:src="@drawable/icon"    
        android:layout_margin="5px"/>
    <LinearLayout 
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        
        <TextView 
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFFFF"
            android:textSize="22px" 
            />
        
        <TextView 
        	android:id="@+id/info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFFFF"
            android:textSize="13px" />
    </LinearLayout>

</LinearLayout>

main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent">

<ListView 
	android:id="@+id/listView"       
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content"
	android:choiceMode="singleChoice" />		    
</LinearLayout>



 

相关文章
|
Android开发 数据格式 XML
解决ListView异步加载网络图片的各种问题(一)
MainActivity如下: package com.example.testlistview; import java.util.ArrayList; import android.
939 0
|
4天前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
41 17
|
15天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
16天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
39 10
|
18天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,并提供一些实用的代码示例。通过阅读本文,您将了解到如何保护自己的网络安全,以及如何提高自己的信息安全意识。
44 10
|
18天前
|
存储 监控 安全
云计算与网络安全:云服务、网络安全、信息安全等技术领域的融合与挑战
本文将探讨云计算与网络安全之间的关系,以及它们在云服务、网络安全和信息安全等技术领域中的融合与挑战。我们将分析云计算的优势和风险,以及如何通过网络安全措施来保护数据和应用程序。我们还将讨论如何确保云服务的可用性和可靠性,以及如何处理网络攻击和数据泄露等问题。最后,我们将提供一些关于如何在云计算环境中实现网络安全的建议和最佳实践。
|
19天前
|
监控 安全 网络安全
网络安全与信息安全:漏洞、加密与意识的交织
在数字时代的浪潮中,网络安全与信息安全成为维护数据完整性、保密性和可用性的关键。本文深入探讨了网络安全中的漏洞概念、加密技术的应用以及提升安全意识的重要性。通过实际案例分析,揭示了网络攻击的常见模式和防御策略,强调了教育和技术并重的安全理念。旨在为读者提供一套全面的网络安全知识框架,从而在日益复杂的网络环境中保护个人和组织的资产安全。
|
16天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们日常生活中不可或缺的一部分。本文将深入探讨网络安全漏洞、加密技术和安全意识等方面的问题,并提供一些实用的建议和解决方案。我们将通过分析网络攻击的常见形式,揭示网络安全的脆弱性,并介绍如何利用加密技术来保护数据。此外,我们还将强调提高个人和企业的安全意识的重要性,以应对日益复杂的网络威胁。无论你是普通用户还是IT专业人士,这篇文章都将为你提供有价值的见解和指导。
|
17天前
|
安全 算法 网络协议
网络安全与信息安全知识分享
本文深入探讨了网络安全漏洞、加密技术以及安全意识三个方面,旨在帮助读者更好地理解和应对网络安全威胁。通过分析常见的网络安全漏洞类型及其防范措施,详细介绍对称加密和非对称加密的原理和应用,并强调提高个人和企业安全意识的重要性,为构建更安全的网络环境提供指导。
33 2
|
17天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:漏洞、加密与意识的艺术
在数字世界的迷宫中,网络安全和信息安全是守护者之剑。本文将揭示网络漏洞的面纱,探索加密技术的奥秘,并强调安全意识的重要性。通过深入浅出的方式,我们将一起走进这个充满挑战和机遇的领域,了解如何保护我们的数字身份不受威胁,以及如何在这个不断变化的环境中保持警惕和适应。
34 1
下一篇
DataWorks