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

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>

 

时间: 2024-08-29 07:59:14

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

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

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;

Android实现Listview异步加载网络图片并动态更新的方法_Android

本文实例讲述了Android实现Listview异步加载网络图片并动态更新的方法.分享给大家供大家参考,具体如下: 应用实例:解析后台返回的数据,把每条都显示在ListView中,包括活动图片.店名.活动详情.地址.电话和距离等. 在布局文件中ListView的定义: <ListView android:id="@id/maplistview" android:background="@drawable/bg" android:layout_width=&qu

Android实现Listview异步加载网络图片并动态更新的方法

本文实例讲述了Android实现Listview异步加载网络图片并动态更新的方法.分享给大家供大家参考,具体如下: 应用实例:解析后台返回的数据,把每条都显示在ListView中,包括活动图片.店名.活动详情.地址.电话和距离等. 在布局文件中ListView的定义: <ListView android:id="@id/maplistview" android:background="@drawable/bg" android:layout_width=&qu

android开发中解决ListView异步加载图片错乱问题

 代码如下 复制代码 : import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import android.content.Context; import android

解决Android ListView异步加载图片乱序问题

在Android所有系统自带的控件当中,ListView这个控件算是用法比较复杂的了,关键是用法复杂也就算了,它还经常会出现一些稀奇古怪的问题,让人非常头疼.比如说在ListView中加载图片,如果是同步加载图片倒还好,但是一旦使用异步加载图片那么问题就来了,这个问题我相信很多Android开发者都曾经遇到过,就是异步加载图片会出现错位乱序的情况.遇到这个问题时,不少人在网上搜索找到了相应的解决方案,但是真正深入理解这个问题出现的原因并对症解决的人恐怕还并不是很多.那么今天我们就来具体深入分析一

ListView异步加载图片(解决图片混淆)

代码下载地址: http://115.com/file/e75ks6jj#ImageLoader_test.zip        由于工作原因,很久没有写博客了,工作中经常遇到ListView异步加载图片的问题,国内的网站上查了N多资料,几乎没有一个可用的,最根本的图片混淆问题都没有得到充分地解决.我的这个例子是借鉴Google Code中的例子,删除了其中的没有必要的代码,完全可行.   该工程由ImageListActivity.ImageAdapter.ImageDownloader三个类

listview异步加载图片并防止错位

android listview 异步加载图片并防止错位 网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertView 但没有异步操作也不会有问题. 我简单分析一下: 当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView. 当 Item1 划出屏幕, Item8 进入屏幕时,

Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如ListView上有100个Item,一屏只显示10个Item,我们知道getView()中convertView是用来复用View对象的,因为一个Item的对应一个View对象,而Ima

iOS开发swift版异步加载网络图片(带缓存和缺省图片)

iOS开发之swift版异步加载网络图片     与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存.      异步加载图片的核心代码如下: ? 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 40 41 42 43 44 45 46 47 48 49 5