提高滑动的效率,需要避免UI线程重绘,主要有两个方法:
ListView滑动停止后才加载可见项
ListView滑动时,取消所有加载项
即,需要增加一个接口:
public class MyAdapter extends BaseAdapter implements AbsListView.OnScrollListener
该接口有两个默认方法:
private int mStart, mEnd;
private static Stirng[] URLS; //用于保存所有可获取图片的地址
public void OnScrollStateChanged(AbsListView view, int scrollState){
if(scrollState == SCROLL_STATE_IDLE){
//加载可见项
mImageLoader.loadImage(mStart, mEnd);
}else{
//停止任务
mImageLoader.cancelAllTasks();
}
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int total){
mStart = firstVisibleItem;
mEnd = firstVisibleItem + visibleItemCount;
//第一次显示时调用
if(mFirstIn == true && visibleItemCount > 0){
mImageLoader,loadImage(mStart, mEnd);
mFirstIn = false;
}
}
修改后的初始化方法为:
public MyAdapter(Context context, List<MyBean> data, ListView listView){
mList = data;
mInflater = LayoutInflater.from(context);
mImageLoader = new ImageLoader(listView);
URLS = new String[data.size()];
for(int i =0;i<data.size();i++){
URLS[i] = data.get(i).MyIconUrl;
}
listView.setOnScrollListener(this);
}
在ImageLoader这个工具类中增加两条声明:
private ListView mListView;
private Set<MyAsyncTask> mTask;
public void loadImage(int start, int end){
//用于加载从start到end的所有图片
for(int i = start;i<end;i++){
String url = MyAdapter.URLS[i];
//从缓存中取出对应图片
Bitmap bitmap = getBitmapFromCache(url);
if(bitmap == null){
MyAsyncTask task = new MyAsyncTask(url);
task.execute(url);
mTask.add(task);
}else{
//缓存中有图片,则直接使用
ImageView imageView = (ImageView)mListView.findViewWithTag(mUrl);
//通过tag查到到对应imageView
if(imageView != null && bitmap != null){
imageView.setImageBitmap(bitmap);
}
}
}
}
在继续增加如下方法:
public void cancelAllTasks(){
if(mTask!= null){
for(MyAsyncTask task:mTask){
task.cancel(false);
}
}
}
另外还有一些方法中的参数需要修改,不过都只是适配一下参数而已,具体小细节就不予记录了。主要完成的就是将显示图片交给滑动状态监听来触发,以实现平滑的滚动,将加载图片的控制权由getView转移到滑动事件,从而使复杂的ListView也可以实现流畅的异步加载
这样的编写程序有很大的弊端,耦合度太高,需要优化某一点小细节,就需要全篇修改,而这不符合面向对象编程的优势,以后如果有机会我尝试一下能否改进。
到此为止,基本上就完成了异步加载网络图片及相关优化。
异步加载的小总结:
通过异步加载,避免了阻塞UI线程
通过LruCache,将已下载的图片放入内存中,这是一级缓存,还有将图片存入硬盘,以便以后更持久的重复使用的二级缓存
通过判断ListView滑动状态,决定何时加载图片
不仅是ListView,任何控件都可以异步加载,且异步加载不仅仅是加载网络图片,所有的耗时操作都可以是异步加载,防止阻塞UI线程,提高用户体验。