解決思路:添加listView的滾動監聽事件,在listView滾動時使加載圖片線程處於等待狀態。當中止活動後,得到當前界面的listView的開始位置和結束位置。而後開啓加載圖片線程。緩存
代碼片斷:網絡
public AsyncImageLoader imageLoader; //聲明圖片加載類的對象異步
在getView中添加listView滑動監聽事件ide
public AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {函數
public void onScrollStateChanged(AbsListView view, int scrollState) {post
switch (scrollState) {學習
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:url
imageLoader.lock();//處於滾動狀態鎖定加載線程spa
break;線程
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
int start = listView.getFirstVisiblePosition();//獲得listView當前屏的開始位置
int end = listView.getLastVisiblePosition(); //獲得結束位置
if (end >= getCount()) {
end = getCount() - 1;
}
imageLoader.setLoadLimit(start, end);//設置要加載圖片的起始位置和結束位置
imageLoader.unlock();//解除鎖定
break;
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
imageLoader.lock();
break;
default:
break;
}
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
};
getView中的圖片加載代碼:
// 異步加載圖片
imageLoader.loadDrawable(position, hotel.getHotelTitlePic(),
new ImageCallback() {
public void imageLoaded(Drawable imageDrawable,
String imageUrl) {
ImageView imageView = (ImageView) listView
.findViewWithTag(imageUrl);
if (imageView != null) {
BitmapDrawable bd = (BitmapDrawable) imageDrawable;
if (bd != null) {
Bitmap bitmap = bd.getBitmap();
BitmapDrawable b = new BitmapDrawable(
toRoundCorner(bitmap, 5)); //將圖片轉換爲圓角,此處函數不便列出。
imageView.setImageDrawable(b);
imageView.setTag("");
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
}
}
}
}
});
listView綁定監聽事件:
listView.setOnScrollListener(onScrollListener);
加載圖片類:
/**
* 異步圖片加載,加載item的小圖片
* @author Administrator
*
*/
public class AsyncImageLoader {
private static final String TAG = "AsyncImageLoader";
public boolean allow = true;
private Object lock = new Object();
private int mStartLoadLimit;
private int mStopLoadLimit;
private boolean firstLoad = true;
//緩存處理類
FileCache fileCache;
public AsyncImageLoader(Context context){
fileCache = new FileCache(context);
}
public void setLoadLimit(int startLoadLimit,int stopLoadLimit){
if(startLoadLimit > stopLoadLimit){
return;
}
mStartLoadLimit = startLoadLimit;
mStopLoadLimit = stopLoadLimit;
synchronized (lock) {
lock.notifyAll();
}
}
public void lock(){
allow = false;
firstLoad = false;
}
public void setFirst(){
firstLoad = true;
}
public void unlock(){
allow = true;
}
public Drawable loadDrawable(final String imageUrl,final ImageCallback imageCallback){
final Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
imageCallback.imageLoaded((Drawable) msg.obj, imageUrl);
}
};
new Thread(){
public void run() {
Drawable drawable=loadImageFromUrl(imageUrl);
if(drawable == null){
// handler.sendMessage(handler.obtainMessage(0, R.drawable.downloadfalse));
return;
}
handler.sendMessage(handler.obtainMessage(0,drawable));
};
}.start();
return null;
}
public Drawable loadDrawable(final int postion, final String imageUrl,final ImageCallback imageCallback){
final Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
imageCallback.imageLoaded((Drawable) msg.obj, imageUrl);
}
};
new Thread(){
public void run() {
if(!allow){
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Drawable drawable= null;
if(firstLoad || (postion>=mStartLoadLimit && postion<=mStopLoadLimit)){ //第一次加載或
//只有在當前屏的item纔會加載
drawable = loadImageFromUrl(imageUrl);
}
if(drawable == null){
return;
}
handler.sendMessage(handler.obtainMessage(0,drawable));
};
}.start();
return null;
}
protected Drawable loadImageFromUrl(String imageurl) {
if(null == imageurl || imageurl.equals("")){
return null;
}
File f = fileCache.getFile(imageurl);
//從SD卡
Drawable d = filetoDrable(f);
if (d != null)
return d;
//從網絡
URL m;
InputStream in = null;
try {
m = new URL(ConstDefinition.HTTPURL+imageurl);
in = (InputStream) m.getContent();
OutputStream os = new FileOutputStream(f);
CopyStream(in, os);
os.close();
return filetoDrable(f);
} catch (Exception ex){
// ex.printStackTrace();
}
return null;
}
public interface ImageCallback{
public void imageLoaded(Drawable imageDrawable,String imageUrl);
}
private void CopyStream(InputStream is, OutputStream os) {
final int buffer_size = 1024;
try {
byte[] bytes = new byte[buffer_size];
for (;;) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
is.close();
os.close();
} catch (Exception ex) {
}
}
private Drawable filetoDrable(File f) {
try {
Drawable drawable = Drawable.createFromStream(new FileInputStream(f) , "src");
Log.i("filetoDrable",f.getName());
return drawable;
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// Log.i("filetoDrable",e.toString());
}catch(OutOfMemoryError e1){
// e1.printStackTrace();
}
return null;
}
}
問題研究:此種方法會很好的提升用戶體驗,但有一個問題,當用戶不但的快速滑動時程序中等待的線程數會愈來愈多,這樣可能會產生問題。但願有更好的解決方案,共同窗習。