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

简介:

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

来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4139998.html

 

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

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

显然,启动加载图片的过程应该是在getView()方法中触发,启动一个线程,然后下载头像图片。这里使用我写的一个开源框架ImageLoaderSamplehttps://github.com/wangjiegulu/ImageLoaderSample)来加载图片,并实现内存缓存和本地缓存。

额--这里不再介绍ImageLoaderSample的用法了,给个传送门:http://www.cnblogs.com/tiantianbyconan/p/3574131.html

 

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

1. Adapter调用NotifyDataChanged的时候

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

也就是说,每当ListView滚动时,getView()方法不断被调用,图片下载的过程不断地执行(当然,ImageLoaderSample中会有缓存,但是内存缓存时有限的,如果内存缓存中找不到要显示的图片,那就需要到文件缓存中查找,需要进行io读写,这个也是相对比较耗时的),显然,这里面还有优化的余地。

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

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

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

 

这样的话,我们就必须要改写BaseAdapter,让它能够监测ListView的滚动状态,并在Adapter中可以获取到当前ListView的滚动状态。所以改造BaseAdapter,ABaseAdapterhttps://github.com/wangjiegulu/AndroidBucket/blob/master/src/com/wangjie/androidbucket/adapter/ABaseAdapter.java):

复制代码
 1 package com.wangjie.androidbucket.adapter;
 2 
 3 import android.widget.*;
 4 import com.wangjie.androidbucket.adapter.listener.OnAdapterScrollListener;
 5 
 6 /**
 7  * Author: wangjie
 8  * Email: tiantian.china.2@gmail.com
 9  * Date: 12/3/14.
10  */
11 public abstract class ABaseAdapter extends BaseAdapter implements AbsListView.OnScrollListener {
12     private OnAdapterScrollListener onAdapterScrollListener;
13     /**
14      * 当前listview是否属于滚动状态
15      */
16     private boolean isScrolling;
17 
18     public boolean isScrolling() {
19         return isScrolling;
20     }
21 
22     public void setOnAdapterScrollListener(OnAdapterScrollListener onAdapterScrollListener) {
23         this.onAdapterScrollListener = onAdapterScrollListener;
24     }
25 
26     protected ABaseAdapter(AbsListView listView) {
27         listView.setOnScrollListener(this);
28     }
29 
30     @Override
31     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
32         if (null != onAdapterScrollListener) {
33             onAdapterScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
34         }
35     }
36 
37     @Override
38     public void onScrollStateChanged(AbsListView view, int scrollState) {
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()方法给外面。

OnAdapterScrollListener这个接口是继承了AbsListView.OnScrollListener,因为这里在Adapter中一景设置了OnScrollListener了,所以如果在外面设置了新的OnScrollListener的话,就会失效了,所以必须提供另外一个setOnAdapterScrollListener,然后再传入一个OnScrollListener,然后在每个方法中进行回调就好了,因为考虑到以后可能会扩展其他的接口方法,所以这里新写了一个接口(为了以后扩展时原来的代码不会被影响,推荐使用OnAdapterScrollSampleListener这个实现类来代替OnAdapterScrollListener这个接口,OnAdapterScrollSampleListener这个类只是对OnAdapterScrollListener的所有方法进行了空实现)。

 

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

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

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

看到木有?

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

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

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

 

本文转自天天_byconan博客园博客,原文链接:http://www.cnblogs.com/tiantianbyconan/p/4139998.html如需转载请自行联系原作者
相关文章
|
12月前
|
数据库 Android开发
Android使用EditText+Listview实现搜索效果(使用room模糊查询)
本文介绍如何在Android中使用EditText与ListView实现搜索功能,并结合Room数据库完成模糊查询。主要内容包括:Room的模糊查询语句(使用`||`代替`+`号)、布局美化(如去除ListView分割线和EditText下划线)、EditText回车事件监听,以及查询逻辑代码示例。此外,还提供了相关扩展文章链接,帮助读者深入了解ListView优化、动态搜索及Room基础操作。
717 65
|
7月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
917 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
8月前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
530 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
12月前
|
Android开发 开发者
Android自定义view之利用drawArc方法实现动态效果
本文介绍了如何通过Android自定义View实现动态效果,重点使用`drawArc`方法完成圆弧动画。首先通过`onSizeChanged`进行测量,初始化画笔属性,设置圆弧相关参数。核心思路是不断改变圆弧扫过角度`sweepAngle`,并调用`invalidate()`刷新View以实现动态旋转效果。最后附上完整代码与效果图,帮助开发者快速理解并实践这一动画实现方式。
263 0
|
10月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
615 11
|
12月前
|
XML Android开发 数据格式
Android利用selector(选择器)实现图片动态点击效果
本文介绍了Android中ImageView的`src`与`background`属性的区别及应用,重点讲解如何通过设置背景选择器实现图片点击动态效果。`src`用于显示原图大小,不拉伸;`background`可随组件尺寸拉伸。通过创建`selector_setting.xml`,结合`setting_press.xml`和`setting_normal.xml`定义按下和正常状态的背景样式,提升用户体验。示例代码展示了具体实现步骤,包括XML配置和形状定义。
534 3
Android利用selector(选择器)实现图片动态点击效果
|
12月前
|
Java Android开发
Android图片的手动放大缩小
本文介绍了通过缩放因子实现图片放大缩小的功能,效果如动图所示。关键步骤包括:1) 在布局文件中设置 `android:scaleType="matrix"`;2) 实例化控件并用 `ScaleGestureDetector` 处理缩放手势;3) 使用 `Matrix` 对图片进行缩放处理。为避免内存崩溃,可在全局配置添加 `android:largeHeap="true"`。代码中定义了 `beforeScale` 和 `nowScale` 变量控制缩放范围,确保流畅体验。
403 8
|
12月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
444 1
|
Android开发 数据格式 XML
Android异步加载图片详解之方式二(3)
main.xml如下:   listviewitem.xml如下:   ...
892 0
|
缓存 Java Android开发
Android异步加载图片详解之方式二(2)
FileCache.java如下: package com.cn.loadImages; import java.io.File; import java.
992 0

热门文章

最新文章