文档章节

android listView滑动停止后加载图片

 风过后
发布于 2014/04/02 15:57
字数 805
阅读 8788
收藏 2

解决思路:添加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;

}

}


问题研究:此种方法会很好的提高用户体验,但有一个问题,当用户不但的快速滑动时程序中等待的线程数会越来越多,这样可能会产生问题。希望有更好的解决方案,共同学习。


© 著作权归作者所有

粉丝 1
博文 17
码字总数 16917
作品 0
成都
私信 提问
加载中

评论(1)

luo_text
luo_text
这个的解决思路是这样的,加入一个限量的消息队列,当用户正在滑动,也就是正常滑动的时候,将你的线程放进消息队列去,进行下载图片那些操作,这是正常的思维。而当用户快速进行滑动,那么你的消息队列很快就会填满的,这个时候就是释放前面的,加入你后面的,而一直快速滑动,就一直重复以上操作,即满了就释放,直到用户停下或者正常的滑动的时候,从消息队列拿出来你的线程,从最后那一个开始下载。
Android ListView滑动过程中图片显示重复错乱闪烁问题解决

最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复、错乱、闪烁的原因及解决方法,顺带提及ListView的缓...

Trinea
2013/08/07
29.1K
4
Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)

最新内容建议直接访问原文:Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类) 介绍总结的一些android公共库,包含缓存(图片缓存、预取缓存)、公共View(下拉及底部...

Trinea
2013/07/28
881
1
总结的一些android公共库

最新最准确内容建议直接访问原文:Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类) 介绍总结的一些android公共库,包含缓存(图片缓存、预取缓存)、公共View(下拉...

Trinea
2012/07/16
353
1
Android ListView复杂列表优化实践

原文:Android ListView复杂列表优化实践 很多社交App都不免会涉及到复杂的列表元素实现,一个列表上面可能大量的图片,不定长的评论列表,给手机端的程序员带来了不少的挑战。本文就是在实现...

叶大侠
2015/02/07
5.4K
18
Android ListView复杂列表优化实践

原文:Android ListView复杂列表优化实践 很多社交App都不免会涉及到复杂的列表元素实现,一个列表上面可能大量的图片,不定长的评论列表,给手机端的程序员带来了不少的挑战。本文就是在实现...

程序袁_绪龙
2015/02/07
6K
1

没有更多内容

加载失败,请刷新页面

加载更多

可见性有序性,Happens-before来搞定

写在前面 上一篇文章并发 Bug 之源有三,请睁大眼睛看清它们 谈到了可见性/原子性/有序性三个问题,这些问题通常违背我们的直觉和思考模式,也就导致了很多并发 Bug 为了解决 CPU,内存,IO ...

tan日拱一兵
14分钟前
2
0
网络七层模型与TCP/UDP

为了使全球范围内不同的计算机厂家能够相互之间能够比较协调的进行通信,这个时候就有必要建立一种全球范围内的通用协议,以规范各个厂家之间的通信接口,这就是网络七层模型的由来。本文首先...

爱宝贝丶
18分钟前
2
0
Jenkins World 贡献者峰会及专家答疑展位

本文首发于:Jenkins 中文社区 原文链接 作者:Marky Jackson 译者:shunw Jenkins World 贡献者峰会及专家答疑展位 本文为 Jenkins World 贡献者峰会活动期间的记录 Jenkins 15周岁啦!Jen...

Jenkins中文社区
35分钟前
8
0
杂谈:面向微服务的体系结构评审中需要问的三个问题

面向微服务的体系结构如今风靡全球。这是因为更快的部署节奏和更低的成本是面向微服务的体系结构的基本承诺。 然而,对于大多数试水的公司来说,开发活动更多的是将现有的单块应用程序转换为...

liululee
50分钟前
7
0
OSChina 周二乱弹 —— 我等饭呢,你是不是来错食堂了?

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @ 自行车丢了:给主编推荐首歌 《クリスマスの夜》- 岡村孝子 手机党少年们想听歌,请使劲儿戳(这里) @烽火燎原 :国庆快来,我需要长假! ...

小小编辑
今天
534
9

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部