开发者社区> 小弟的谷哥> 正文

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

简介: MainActivity如下: package com.example.testlistview; import java.util.ArrayList; import android.
+关注继续查看

MainActivity如下:

package com.example.testlistview;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;
//解决的问题:
//1 ListView异步加载网络图片
//2 ListView滑动时,图片错位
public class MainActivity extends Activity {
    private ListView listView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
    public void initView(){
    	listView=(ListView) findViewById(R.id.listView);
    	ArrayList<ListViewItem> arrayList=new ArrayList<ListViewItem>();
    	
			ListViewItem item1=new ListViewItem("xxxx", "http://images.csdn.net/20121018/zazhi-68-78-1018.jpg");
			arrayList.add(item1);
			
			ListViewItem item2=new ListViewItem("xxxx", "http://info-database.csdn.net/Upload/2012-10-08/zazhi-210-90-1008.jpg");
			arrayList.add(item2);
			
			ListViewItem item3=new ListViewItem("xxxx", "http://images.csdn.net/20121119/20111211223655841.jpg");
			arrayList.add(item3);
			
			ListViewItem item4=new ListViewItem("xxxx", "http://images.csdn.net/20121119/20120619174604972.jpg");
			arrayList.add(item4);
			
			ListViewItem item5=new ListViewItem("xxxx", "http://csdnimg.cn/www/images/pic_foot_report110.png");
			arrayList.add(item5);
			
			ListViewItem item6=new ListViewItem("xxxx", "http://csdnimg.cn/www/images/pic_foot_report.png");
			arrayList.add(item6);		
			
			ListViewItem item7=new ListViewItem("xxxx", "http://csdnimg.cn/www/images/pic_foot_BNIA.png");
			arrayList.add(item7);
			
			ListViewItem item8=new ListViewItem("xxxx", "http://csdnimg.cn/www/images/pic_foot_gongshang.png");
			arrayList.add(item8);
			
			ListViewItem item9=new ListViewItem("xxxx", "http://images.csdn.net/20120803/logo-qixing02.jpg");
			arrayList.add(item9);
			
			ListViewItem item10=new ListViewItem("xxxx", "http://images.csdn.net/20120726/quanjing-logo-shouye.jpg");
			arrayList.add(item10);
			
			ListViewItem item11=new ListViewItem("xxxx", "http://images.csdn.net/20120726/nhn-logo-shouye.jpg");
			arrayList.add(item11);
			
			ListViewItem item12=new ListViewItem("xxxx", "http://images.csdn.net/20120510/shanghai-jiaoda-logo.jpg");
			arrayList.add(item12);
			
			ListViewItem item13=new ListViewItem("xxxx", "http://images.csdn.net/20120312/bigman2.gif");
			arrayList.add(item13);
			
			ListViewItem item14=new ListViewItem("xxxx", "http://images.csdn.net/20120216/csdn2.gif");
			arrayList.add(item14);
			
			ListViewItem item15=new ListViewItem("xxxx", "http://images.csdn.net/20121109/win8_100x74.jpg");
			arrayList.add(item15);
		
			ListViewItem item16=new ListViewItem("xxxx", "http://images.csdn.net/20120816/cf-20120816.jpg");
			arrayList.add(item16);
			
			ListViewItem item17=new ListViewItem("xxxx", "http://images.csdn.net/20120704/bi05.jpg");
			arrayList.add(item17);
			
			ListViewItem item18=new ListViewItem("xxxx", "http://images.csdn.net/20120816/amd-20120816.jpg");
			arrayList.add(item18);
	
		   MyListViewAdapter adapter=new MyListViewAdapter(arrayList, MainActivity.this,listView);
		   
    	   listView.setAdapter(adapter);
    }
}


ListViewItem的Bean如下:

package com.example.testlistview;
public class ListViewItem {
	String content;
	String imageURL;

	public ListViewItem(String content, String imageURL) {
		super();
		this.content = content;
		this.imageURL = imageURL;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getImageURL() {
		return imageURL;
	}

	public void setImageURL(String imageURL) {
		this.imageURL = imageURL;
	}

}


自定义BaseAdapter如下:

package com.example.testlistview;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.example.loadimages.AsycPicLoader;
import com.example.loadimages.AsycPicLoader.ImageCallback;
public class MyListViewAdapter extends BaseAdapter{
      private ArrayList<ListViewItem> mArrayList;
      private Context mContext;
      private AsycPicLoader asycPicLoader;
      private ListView listView;
      private HashMap<Integer, View> hashMap;
 
      public MyListViewAdapter(ArrayList<ListViewItem> mArrayList,Context mContext,ListView listView ) {
  		super();
  		this.mArrayList = mArrayList;
  		this.mContext = mContext;
  		this.listView=listView;
  	    asycPicLoader=new AsycPicLoader();
  	    hashMap=new HashMap<Integer, View>();
  	}

	public int getCount() {
		if (mArrayList==null) {
			return 0;
		} else {
			return mArrayList.size();
		}
		
	}

	public Object getItem(int position) {
		if (mArrayList==null) {
			return null;
		} else {
            return mArrayList.get(position);
		}
	}

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

	public View getView(int position, View convertView, ViewGroup parent) {
		//从HashMap中取出此position对应的convertView
		convertView=hashMap.get(position);
		ViewHolder holder=null;
		if (convertView==null) {
			holder=new ViewHolder();
			convertView=LayoutInflater.from(this.mContext).inflate(R.layout.listviewitem, null, false);
			holder.textView=(TextView) convertView.findViewById(R.id.textView);
		    holder.imageView=(ImageView) convertView.findViewById(R.id.imageview);
		    convertView.setTag(holder);
		} else {
            holder=(ViewHolder) convertView.getTag();
		}
		
	
		//设置ListView的每个item
		if (this.mArrayList!=null) {
			ListViewItem listViewItem=this.mArrayList.get(position);
			if (holder.textView!=null) {
				holder.textView.setText(listViewItem.getContent());
			}
			if (holder.imageView!=null) {
				try {
					this.loadImage(listViewItem.getImageURL(),holder.imageView);
				} catch (Exception e) {
					e.printStackTrace();
				}
					
			}
		}	    
		
		//设置完成后的convertView放在HashMap中
	    if (!hashMap.containsKey(position)) {
	    	hashMap.put(position, convertView);
		}
		
		return convertView;
	}
	
	
	public void loadImage(String imgageURL, final ImageView imageView) {
		asycPicLoader.loadImages(imgageURL, new ImageCallback() {
			public void showLoadedImage(Drawable imageDrawable) {
				if (imageDrawable!=null&&imageDrawable.getIntrinsicWidth()>0) {
					imageView.setImageDrawable(imageDrawable);
				}	
			}
		});
	}
	
	private class ViewHolder{
		ImageView imageView;
		TextView textView;
	}
      
}


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

package com.example.loadimages;
import java.io.IOException;
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;
import android.util.Log;
public class AsycPicLoader {
   private Map<String, SoftReference<Drawable>> softReferenceMap;
   //构造方法
   public AsycPicLoader(){
	   softReferenceMap=new HashMap<String, SoftReference<Drawable>>();
   }
   //加载图片
   public Drawable loadImages(final String imageURL,final ImageCallback imageCallback){
	   //如果图片在SoftReference中,则将其取出
	   if (softReferenceMap.containsKey(imageURL)) {
		  SoftReference<Drawable> softReference=softReferenceMap.get(imageURL);
		  if (softReference!=null) {
			  Log.i("xx", "从缓存中取出来");
			 return softReference.get();
		}
	 }
	   //如果图片不在SoftReference中,则从网络获取图片.
	   final Handler handler=new Handler(){
		   @Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Drawable drawable=(Drawable) msg.obj;
			imageCallback.showLoadedImage(drawable);
		}
	   };
	   new Thread(){
		  public void run() {
			  super.run();
			  Drawable drawable=LoadImageFromUrl(imageURL);
			  softReferenceMap.put(imageURL, new SoftReference<Drawable>(drawable));
			  Message message=new Message();
			  message.obj=drawable;
			  handler.sendMessage(message); 
		  };
	   }.start();
	   return null;
   }
   
  //从网络获取图片
   private Drawable LoadImageFromUrl(String url){
	   try {
		return Drawable.createFromStream((new URL(url)).openStream(), "src");
	}  catch (IOException e) {
		e.printStackTrace();
	}   
     return null;
   }
   
   //定义一个回调接口.用于图片下载完成后,在ImageView中显示图片
   public interface ImageCallback {
	   public void showLoadedImage(Drawable imageDrawable);
	}

}


 


main.xml如下:

<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/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
     >
        
    </ListView>

</RelativeLayout>


listviewitem.xml如下:

<?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="50dip"
    android:orientation="horizontal" >   
    <ImageView 
        android:id="@+id/imageview"
        android:layout_width="50dip" 
        android:layout_height="50dip"     
     />
    
    <TextView 
        android:id="@+id/textView"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:text="haha"
        android:layout_marginLeft="150dip"
     />  
</LinearLayout>


 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
WebView加载页面的两种方式——网络页面和本地页面
WebView加载页面的两种方式 一、加载网络页面   加载网络页面,是最简单的一种方式,只需要传入http的URL就可以,实现WebView加载网络页面 代码如下图: 二、加载本地页面   1、加载assets目录下的HTML页面: 加载assets目录的页面,大多数可以用来做页面数据的存储打包...
1345 0
[Android]ListView的Adapter.getView()方法中延迟加载图片的优化
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4139998.html   举个例子吧,以好友列表为例 ListView中每个Item表示一个好友,每个好友中都有一个头像,需要从服务端加载到本地,然后显示在item中。
784 0
实用技巧:使用 jQuery 异步加载 JavaScript 脚本
  JavaScript 加载器在 Web 开发中是非常强大和有用的工具。目前流行的几个加载器,像 curljs、LABjs 和 RequireJS 使用都很广泛。他们功能强大的,但有些情况下可以有更简单的方案。
905 0
解决ListView嵌套ListView遇到的问题
<div class="entry-content"> <p>Listview嵌套会造成的问题主要是子listview的高度错误导致内容不能正常显示完,解决这个问题,我个人第一个想法就是重新计算子listview的高度,代码如下:</p> <pre><code>private void setListViewHeightBasedOnChildren(ListView listView
1699 0
利用WPF的ListView进行大数据量异步加载
原文:利用WPF的ListView进行大数据量异步加载      由于之前利用Winform的ListView进行大数据量加载的时候,诟病良多,所以今天试着用WPF的ListView来做了一下,结果没有让我失望,我将一个拥有43000行,510列的csv文件导入到了ListView中,总共耗时在10s左右,并且在导入的过程中,软件界面上的提示信息一直在提示当前导入了多少条。
1291 0
+关注
小弟的谷哥
welcome
766
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载