android listview延迟加载图片,[Android]ListView的Adapter.getView()方法中延迟加载图片的优化...

以下内容为原创,欢迎转载,转载请注明

来自天天博客:外链网址已屏蔽

举个例子吧,以好友列表为例

ListView中每个Item表示一个好友,每个好友中都有一个头像,需要从服务端加载到本地,然后显示在item中。

显然,启动加载图片的过程应该是在getView()方法中触发,启动一个线程,然后下载头像图片。这里使用我写的一个开源框架外链网址已屏蔽)来加载图片,并实现内存缓存和本地缓存。

额--这里不再介绍ImageLoaderSample的用法了,给个传送门:外链网址已屏蔽

再来看看getView()方法的调用时机:

1. Adapter调用NotifyDataChanged的时候

2. ListView滚动时,也就是convertView不断复用的时候。

也就是说,每当ListView滚动时,getView()方法不断被调用,图片下载的过程不断地执行(当然,

怎么去优化这里?只要让ListView滚动的时候图片显示的时候不要去进行io读写就好了,具体逻辑如下:

-如果调用GetView方法时,ListView处于停止状态,则先去内存中查找头像图片;如果内存图片存在,则显示内存中保存好的图片;如果内存图片不存在,则继续到文件缓存中找,如果文件缓存图片存在,则显示文件缓存中的图片;如果文件缓存图片不存在,则根据url去网络下载这张图片,然后显示;

-如果调用getView方法时,ListView处于滚动状态,则去内存中查找头像的图片;如果内存图片存在,则显示内存中保存好的图片;如果内存图片不存在,则显示一张默认的图片(省去了从文件缓存中找图片和网络中去请求图片的步骤)。

这样的话,我们就必须要改写BaseAdapter,让它能够监测ListView的滚动状态,并在Adapter中可以获取到当前ListView的滚动状态。所以改造BaseAdapter,外链网址已屏蔽):

1 packagecom.wangjie.androidbucket.adapter;2

3 import android.widget.*;4 importcom.wangjie.androidbucket.adapter.listener.OnAdapterScrollListener;5

6 /**

7 * Author: wangjie8 * Email: tiantian.china.2@9 * Date: 12/3/14.10 */

11 public abstract class ABaseAdapter extends BaseAdapter implementsAbsListView.OnScrollListener {12 privateOnAdapterScrollListener onAdapterScrollListener;13 /**

14 * 当前listview是否属于滚动状态15 */

16 private booleanisScrolling;17

18 public booleanisScrolling() {19 returnisScrolling;20 }21

22 public voidsetOnAdapterScrollListener(OnAdapterScrollListener onAdapterScrollListener) {23 this.onAdapterScrollListener =onAdapterScrollListener;24 }25

26 protectedABaseAdapter(AbsListView listView) {27 listView.setOnScrollListener(this);28 }29

30 @Override31 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, inttotalItemCount) {32 if (null !=onAdapterScrollListener) {33 onAdapterScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);34 }35 }36

37 @Override38 public void onScrollStateChanged(AbsListView view, intscrollState) {39 if (null !=onAdapterScrollListener) {40 onAdapterScrollListener.onScrollStateChanged(view, scrollState);41 }42

43 //设置是否滚动的状态

44 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { //不滚动状态

45 isScrolling = false;46 this.notifyDataSetChanged();47 } else{48 isScrolling = true;49 }50 }51 }

如上述代码所示,该Adapter实现了AbsListView.OnScrollListener,并在构造方法中给ListView绑定了OnScrollListener,在实现的onScrollStateChanged方法中获取到当前滚动状态,并且保存这个状态isScrolling,并暴露isScrolling()方法给外面。

然后我们编写一个MyAdapter继承ABaseAdapter,然后,在getView()方法中,需要显示头像的时候调用如下方法:

// 如果在滚动(从内存中查找,找不到也不进行网络请求)

ImageLoader.getInstances().displayImage(headUrl, headIv, null, R.drawable.default_head, isScrolling());

看到木有?

1. displayImage()方法发生了改变,多了最后一个参数isOnlyMemory这个参数,表示是否只是在内存缓存中找这张图片,如果没有就不再继续找下去了(displayImage原来的方法我还留着,所以不会影响之前的代码)。

2. 调用了isScrolling()方法,作为参数isOnlyMemory的值,表示,如果正在滚动的话,就只在缓存中找这张图片。

这样,运行原来的代码试试吧,是不是效率快了一些?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值