main.xml(先看主页面布局,界面很简单,只有一个ListView)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
book_item_adapter.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70.0dip"
android:background="@drawable/item"
android:drawingCacheQuality="high"
android:minHeight="70.0dip"
android:orientation="horizontal" >
<ImageView
android:id="@+id/sItemIcon"
android:layout_width="42.0dip"
android:layout_height="54.0dip"
android:layout_margin="10.0dip"
android:background="@drawable/rc_item_bg"
android:padding="2.0dip"
android:scaleType="fitXY" />
<TextView
android:text="斗破苍穹"
android:id="@+id/sItemTitle"
android:layout_width="fill_parent"
android:layout_height="30.0dip"
android:layout_alignTop="@+id/sItemIcon"
android:layout_toRightOf="@+id/sItemIcon"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#ffffff"
android:textSize="18.0sp" />
</RelativeLayout>ImageAndText(这个比较简单,分别对应item里面的2个控件,一个是图片,一个是文本)
package cn.wangmeng.test;
public class ImageAndText {
private String imageUrl;
private String text;
public ImageAndText(String imageUrl, String text) {
this.imageUrl = imageUrl;
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public String getText() {
return text;
}
}
AsyncListImage
package cn.wangmeng.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class AsyncListImage extends Activity {
private ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//布局只是一个listView控件
setContentView(R.layout.main);
//listView
list=(ListView)findViewById(R.id.list);
//data
List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
for (int i = 0; i < 100; i++) {
ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");
ImageAndText test1=new ImageAndText("http://www.pfwx.com/files/article/image/0/54/54s.jpg", "test1");
ImageAndText test2=new ImageAndText("http://www.pfwx.com/files/article/image/0/4/4s.jpg","test2");
ImageAndText test3=new ImageAndText("http://www.pfwx.com/files/article/image/9/9760/9760s.jpg","test3");
ImageAndText test4=new ImageAndText("http://www.pfwx.com/files/article/image/3/3382/3382s.jpg","test4");
ImageAndText test5=new ImageAndText("http://www.pfwx.com/files/article/image/3/3237/3237s.jpg","test5");
dataArray.add(test);
dataArray.add(test1);
dataArray.add(test2);
dataArray.add(test3);
dataArray.add(test4);
dataArray.add(test5);
}
//adapter
ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);
//setAdapter
list.setAdapter(adapter);
}
}ImageAndTextListAdapter
package cn.wangmeng.test;
import java.util.ArrayList;
import java.util.List;
import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class ImageAndTextListAdapter extends BaseAdapter{
private LayoutInflater inflater;
private ListView listView;
private AsyncImageLoader asyncImageLoader;
private List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
this.listView = listView;
asyncImageLoader = new AsyncImageLoader();
inflater = activity.getLayoutInflater();
dataArray=imageAndTexts;
//设置滑动事件的监听
listView.setOnScrollListener(onScrollListener);
}
@Override
public int getCount() {
return dataArray.size();
}
@Override
public Object getItem(int position) {
if(position >= getCount()){
return null;
}
return dataArray.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/**页面一旦加载,就获取可显示item的布局,并且设置tag,待滑动时候,复用布局*/
if (convertView == null) {
convertView = inflater.inflate(R.layout.book_item_adapter, null);
}
convertView.setTag(position);
/**
* 获取可见item的data数据
*/
ImageAndText imageAndText = (ImageAndText) getItem(position);
String imageUrl = imageAndText.getImageUrl();
//设置值
TextView textView = (TextView) convertView.findViewById(R.id.sItemTitle);
textView.setText(imageAndText.getText());//加载TEXT
ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
//一上来就先加载默认的图片
iv.setBackgroundResource(R.drawable.rc_item_bg);
/**
* 在加载默认的图片同时,也进行异步请求图片下载
*/
asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
@Override
public void onImageLoad(Integer pos, Drawable drawable) {
//获取设置标记的视图
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundDrawable(drawable);
}
}
//加载不成功的图片处理
@Override
public void onError(Integer pos) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundResource(R.drawable.rc_item_bg);
}
}
});
return convertView;
}
public void loadImage(){
int start = listView.getFirstVisiblePosition();
int end =listView.getLastVisiblePosition();
if(end >= getCount()){
end = getCount() -1;
}
asyncImageLoader.setLoadLimit(start, end);
asyncImageLoader.unlock();
}
AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
asyncImageLoader.lock();
break;
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
loadImage();
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
asyncImageLoader.lock();
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
};
}
AsyncImageLoader
package cn.wangmeng.test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
public class AsyncImageLoader {
private Object lock = new Object();
private boolean mAllowLoad = true;
private boolean firstLoad = true;
private int mStartLoadLimit = 0;
private int mStopLoadLimit = 0;
final Handler handler = new Handler();
private HashMap<String, SoftReference<Drawable>> imageCache;
// 设置需要加载图片的position(可显示的位置区域)
public void setLoadLimit(int startLoadLimit, int stopLoadLimit) {
if (startLoadLimit > stopLoadLimit) {
return;
}
mStartLoadLimit = startLoadLimit;
mStopLoadLimit = stopLoadLimit;
}
/**
* 枷锁--阻塞线程
*/
public void lock() {
mAllowLoad = false;
firstLoad = false;
}
/**
* 解锁--loadDrawable加载图片
*/
public void unlock() {
mAllowLoad = true;
synchronized (lock) {
lock.notifyAll();
}
}
/*******************************************************
* 构造器--初始化图片缓存(软引用)
*/
public AsyncImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();
}
/**
* 进行图片异步加载的方法 参数:pos,url,接口
*/
public Drawable loadDrawable(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
new Thread() {
@Override
public void run() {
/**
* 初始化时候, !mAllowLoad为false, 就开始阻塞线程
*/
if (!mAllowLoad) {// 先阻塞线程
synchronized (lock) {// 加锁
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 界面一旦展现就会执行
*/
if (mAllowLoad && firstLoad) {
LoadImg(pos, imageUrl, imageCallback);
}
/**
* 页面初始化展现,会执行这个方法 滑动暂停会执行该方法
*/
if (mAllowLoad && pos <= mStopLoadLimit
&& pos >= mStartLoadLimit) {
LoadImg(pos, imageUrl, imageCallback);
}
}
}.start();
return null;
}
public void LoadImg(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
/**
* 首先先判断缓存中有没有,如果缓存中包含某个Key值, 就从缓存中获取某个url,得到软引用内存里面的对象
*/
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
final Drawable drawable = softReference.get();
// 如果软引用里面的图片没有被回收,就进行页面加载即可
if (drawable != null) {
// 通过handler消息机制,在主线程进行更新ui即可
handler.post(new Runnable() {
@Override
public void run() {
if (mAllowLoad) {
imageCallback.onImageLoad(pos, drawable);
} else {
imageCallback.onError(pos);
}
}
});
return;
}
}
// 尝试从URL中加载
try {
final Drawable drawable = loadImageFromUrl(imageUrl);
// 如果图片获取成功了
if (drawable != null) {
// 放到缓存中
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
}
// 通过handler消息机制,在主线程进行更新ui即可
handler.post(new Runnable() {
@Override
public void run() {
if (mAllowLoad) {
imageCallback.onImageLoad(pos, drawable);
}
}
});
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onError(pos);
}
});
e.printStackTrace();
}
}
// 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
public static Drawable loadImageFromUrl(String url) throws IOException {
URL m;
InputStream i = null;
m = new URL(url);
i = (InputStream) m.getContent();
Drawable d = Drawable.createFromStream(i, "src");
return d;
}
// 回调函数
public interface ImageCallback {
public void onImageLoad(Integer t, Drawable drawable);
public void onError(Integer t);
}
}
原文:http://blog.csdn.net/u013210620/article/details/47844471