有些时候ListView的每个item的内容可能比较复杂,需要一系列的操作才能完成,比较耗时,此时应该用异步加载的方式去获取数据,然而仅仅通过这样处理有时并不能达到很好的效果,item很多的时候(比如有几百上千项)一直往下滑动也可能会造成界面卡顿或者OOM,这是因为每滑过一个item时都会试图用异步去请求数据,而数据还没有返回或已返回时已经滑到下面的item中了,这种情况这样做是非常浪费资源的。
我们刷朋友圈或微博的时候细心一点可以发现,加载的时候大概分两步
- 请求基本的json数据,生成ListView
- 在滑动停下来的时候才去加载图片等数据
不多扯了,直接说实现部分:
封装一个LazyListView继承自ListView
package com.turbo.listviewtest;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.widget.AbsListView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* 懒加载ListView(只在ListView滑动截止时才加载复杂数据)
* Created by Turbo on 2015/12/4.
*/
public class LazyListView extends ListView implements AbsListView.OnScrollListener{
private static final String TAG = "LazyListView";
private OnScrollListener onScrollListener;
private int oldVisibleItemCount=0;
private OnLazyLoadListener onLazyLoadListener;
//记录Item的懒加载情况
//比如(1,true)表示为position为1的item已经懒加载过了
//(2,false) 表示postion为2的item还没有被懒加载
private SparseArray<Boolean> itemsNow;
public LazyListView(Context context) {
super(context);
init();
}
public LazyListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LazyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//调用父类的设置监听方法监听滑动事件
super.setOnScrollListener(this);
itemsNow=new SparseArray<>();
}
/**
* 覆盖setOnScrollListener方法截取回调
* @param l
*/
@Override
public void setOnScrollListener(OnScrollListener l) {
this.onScrollListener=l;
}
/**
* 当ListView出现滑动时会回调这个方法
* 但ListView首次显示时并没有滑动,所以还需要通过onScroll方法判断一下ListView的首次展示
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//Log.d(TAG, "onScrollStateChanged->