Android ListView优化
2016-06-04 19:00
417 查看
在Android的控件中,ListView是比较麻烦的一个。也是比较吃内存的(如果item很多的话)。那么有没有什么方式可以优化一下呢?
ListView是可以优化的,但是得先搞明白Adapter才行。不清楚Adapter,就没法说ListView的优化问题。
为此,我们需要自己实现一个继承自BaseAdapter的实现类MyAdapter.
参考文章:http://mobile.51cto.com/abased-445617.htm
这里先提出可以优化的点:
1、利用Android的Recycle机制,只去实例化必要的View对象。
2、利用Android提供的ViewHolder对象,避免findViewById()这个方法的重复调用。
3、监听ListView的滚动事件,根据情况,合理加载数据。
解释:
不管是什么屏幕,长和宽是一定的,每一屏能显示的ListView的项(item)是有限的,假设最大能显示item_n。那么当屏幕向上滑动时,新的item_(n+1)在底部出现必然伴随最上面一个item_0的不可见。那么那个不可见的item怎么处理呢?肯定不会直接销毁掉,那多浪费资源啊,直接把item_0的View给item_(n+1)用不就是一种理想状态吗?这就是Android的Recycle机制。
接着上面的讲,既然item_(n+1)的View是item_0的,那么View中包含的各种控件也肯定是存在的,那item_0干嘛不把控件对象也一起给item_(n+1)呢,好人做到底嘛。其实View对象中有一个成员viewHolder,这里面是可以存储控件对象的。那么item_(n+1)在拿到View的时候,直接去访问View的viewHolder对象,就拿到item_0的控件对象了。这样item_(n+1)就少了findViewById()这个方法的调用。
由以上两步,就实现了View对象的最小量创建。同时实现了各控件只获取一次(对已同一个View)的操作。这样就避免了很多重复性质的操作。
同时在用户使用时,可能手指是滑得很快的,对于那些一闪而过的item_x,我们有必要重视它吗?基本没必要,用户都不关心,我们瞎操心个什么蛋。对于这些一闪而过的item,像一些网上的图片资源是显然没必要加载的,拖延反应速度不说,关键还浪费流量。所以说,在用户快速滚动时,我们只需要对不确定的item_x只加载必要的数据就行了。
解释完了,上代码看一下。
先看下Android2.3的源码--SimpleAdapter.java
下面贴一下自己的代码:
从代码中可以看出,这里已经使用了ViewHolder,这就避免了每次都去通过findViewById()来获取控件对象。
至于第三点的优化,则只需要监听滚动事件,在滚动停止的时候再去加载全部数据,在滚动过程中只加载不要的简单数据,这里就不贴代码了。
ListView是可以优化的,但是得先搞明白Adapter才行。不清楚Adapter,就没法说ListView的优化问题。
为此,我们需要自己实现一个继承自BaseAdapter的实现类MyAdapter.
参考文章:http://mobile.51cto.com/abased-445617.htm
这里先提出可以优化的点:
1、利用Android的Recycle机制,只去实例化必要的View对象。
2、利用Android提供的ViewHolder对象,避免findViewById()这个方法的重复调用。
3、监听ListView的滚动事件,根据情况,合理加载数据。
解释:
不管是什么屏幕,长和宽是一定的,每一屏能显示的ListView的项(item)是有限的,假设最大能显示item_n。那么当屏幕向上滑动时,新的item_(n+1)在底部出现必然伴随最上面一个item_0的不可见。那么那个不可见的item怎么处理呢?肯定不会直接销毁掉,那多浪费资源啊,直接把item_0的View给item_(n+1)用不就是一种理想状态吗?这就是Android的Recycle机制。
接着上面的讲,既然item_(n+1)的View是item_0的,那么View中包含的各种控件也肯定是存在的,那item_0干嘛不把控件对象也一起给item_(n+1)呢,好人做到底嘛。其实View对象中有一个成员viewHolder,这里面是可以存储控件对象的。那么item_(n+1)在拿到View的时候,直接去访问View的viewHolder对象,就拿到item_0的控件对象了。这样item_(n+1)就少了findViewById()这个方法的调用。
由以上两步,就实现了View对象的最小量创建。同时实现了各控件只获取一次(对已同一个View)的操作。这样就避免了很多重复性质的操作。
同时在用户使用时,可能手指是滑得很快的,对于那些一闪而过的item_x,我们有必要重视它吗?基本没必要,用户都不关心,我们瞎操心个什么蛋。对于这些一闪而过的item,像一些网上的图片资源是显然没必要加载的,拖延反应速度不说,关键还浪费流量。所以说,在用户快速滚动时,我们只需要对不确定的item_x只加载必要的数据就行了。
解释完了,上代码看一下。
先看下Android2.3的源码--SimpleAdapter.java
public View getView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mResource); } private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) { View v; if (convertView == null) { v = mInflater.inflate(resource, parent, false); } else { v = convertView; } bindView(position, v); return v; }其中convertView就是那个回收循环使用的View,第一屏的item在创建时convertView是null,当屏幕滑动后convertView就是Android的Recycle机制回收的View.从Android2.3中SimpleAdapter.java的代码中可以看出,android源码其实也是使用了Android的Recycle回收机制的。
下面贴一下自己的代码:
@Override public View getView(int position, View continer, ViewGroup arg2) { ViewHolder holder; if(continer == null){ continer = inflater.inflate(R.layout.array_item, null); holder = new ViewHolder(); holder.imageView = (ImageView) continer.findViewById(R.id.img); holder.title_tv = (TextView) continer.findViewById(R.id.title); holder.content_tv = (TextView) continer.findViewById(R.id.content); continer.setTag(holder); }else{ holder = (ViewHolder) continer.getTag(); } holder.imageView.setBackgroundResource(itemList.get(position).img_id); holder.title_tv.setText(itemList.get(position).title); holder.content_tv.setText(itemList.get(position).content); return continer; } class ViewHolder{ public ImageView imageView; public TextView title_tv; public TextView content_tv; }
从代码中可以看出,这里已经使用了ViewHolder,这就避免了每次都去通过findViewById()来获取控件对象。
至于第三点的优化,则只需要监听滚动事件,在滚动停止的时候再去加载全部数据,在滚动过程中只加载不要的简单数据,这里就不贴代码了。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories