您的位置:首页 > 移动开发 > Android开发

android listView滑动停止后加载图片

2015-08-05 21:43 661 查看
摘要: android listView在用使用Viewholder以后性能会好很多,但是再滑动的过程中还会有卡顿情况,这里本人试图解决在滑动停止后在加载图片,这样程序的流畅度很提升很多。

解决思路:添加listView的滚动监听事件,在listView滚动时使加载图片线程处于等待状态。当停止活动后,获得当前界面的listView的开始位置和结束位置。然后开启加载图片线程。

代码片段:

public AsyncImageLoader imageLoader; //声明图片加载类的对象

在getView中添加listView滑动监听事件

public AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {

public void onScrollStateChanged(AbsListView view, int scrollState) {

switch (scrollState) {

case AbsListView.OnScrollListener.SCROLL_STATE_FLING:

imageLoader.lock();//处于滚动状态锁定加载线程

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;

}

}

问题研究:此种方法会很好的提高用户体验,但有一个问题,当用户不但的快速滑动时程序中等待的线程数会越来越多,这样可能会产生问题。希望有更好的解决方案,共同学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息