标签:setonscrolllistener softreference synchronized createfromstream thread
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); } }
标签:setonscrolllistener softreference synchronized createfromstream thread
原文地址:http://blog.csdn.net/u013210620/article/details/47844471