浅谈ListView之convertView和viewHolder
来源:互联网 发布:日语翻译发音软件 编辑:程序博客网 时间:2024/05/29 04:57
先就ListView优化问题提出几点看法:
1、复用已经生成的convertView;
2、添加viewHolder类;
3、缓存数据(图片缓存);
4、分页加载。
1、convertView的复用
ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,就会大大改善性能。
<span style="background-color:rgb(204,204,204)">BaseAdapter适配器里有个getView()需要重写public View getView(int position,View converView,ViewGroup parent) { //省略。。。。。。}</span>
这个convertView其实就是最关键的部分 原理上讲 当ListView滑动的过程中 会有item被滑出屏幕 而不再被使用 这时候Android会回收这个条目的view 这个view也就是这里的convertView。<pre name="code" id="best-content-1572584631" class="best-text mb-10" style="margin-top:0px; margin-bottom:10px; padding:0px; font-family:arial,'courier new',courier,宋体,monospace; white-space:pre-wrap; word-wrap:break-word; background-color:rgb(241,254,221)">当item1被移除屏幕的时候 我们会重新new一个View给新显示的item_new 而如果使用了这个convertView 我们其实可以复用它 这样就省去了new View的大量开销。
public View getView(int position, View convertView, ViewGroup parent) {View view = null;if (convertView != null) {view = convertView;//复用了回收的view 只需要直接作内容填充的修改就好了} else {view = new Xxx(...);//没有供复用的view 按一般的做法新建view}return view;}
小demo:
static class ViewHolder{public TextView mSelectAlbumName;public MyImageView mAlbumView;private TextView mImageCounts;}这里,static关键字的作用就是保证该类在内存中只有一个对象,也就是只有一块内存空间,所以不会ViewHolder holder = new ViewHolder()一次就会开辟一块新地址的,不管new几次,都是指向第一次new时开辟的地址,所有引用共用这一地址,即节省内存、又提高效率。
@Overridepublic View getView(int position, View convertView, ViewGroup parent){ final ViewHolder viewHolder; String path = albumList.get(position).getPhotoList().get(0).getPath(); if (convertView == null) { viewHolder = new ViewHolder(); convertView = mInflater.inflate(R.layout.select_album_grid_item, null); viewHolder.mSelectAlbumName = (TextView)convertView.findViewById(R.id.txtSelectName); viewHolder.mAlbumView = (MyImageView)convertView.findViewById(R.id.imgAlbum); viewHolder.mImageCounts = (TextView)convertView.findViewById(R.id.group_count); viewHolder.mAlbumView.setOnMeasureListener(new OnMeasureListener() { @Override public void onMeasureSize(int width, int height) { mPoint.set(width, height); } }); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.mSelectAlbumName.setText(albumList.get(position).getName()); viewHolder.mImageCounts.setText(albumList.get(position).getCount()+" "+context.getString(R.string.pictures)); viewHolder.mAlbumView.setTag(path); Bitmap bitmap = ImageLoader.getInstance().loadNativeImage(path, mPoint, new NativeImageCallBack() {@Overridepublic void onImageLoader(Bitmap bitmap, String path) {ImageView mImageView = (ImageView)mGridView.findViewWithTag(path); if(bitmap != null && mImageView != null) {mImageView.setImageBitmap(bitmap);} } }); if(bitmap != null) { viewHolder.mAlbumView.setImageBitmap(bitmap); } return convertView; }
2、viewHolder类的使用
在getView方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个子View,如:一个TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。当第二次重用convertView时,只需从convertView中getTag取出来就可以了。
setTag()
(设置标签)是将view封装起来,以便下次复用,getTag
()(获取标签)是得到封装的view。
- 浅谈ListView之convertView和viewHolder
- ListView性能优化之convertView和ViewHolder
- Listview优化之convertView,viewHolder
- ListView中ConvertView和ViewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的性能优化之convertView和viewHolder
- ListView的优化之复用convertView和利用ViewHolder
- ListView的性能优化之convertView和viewHolder
- 八大内部排序 -- 选择排序
- 将一个随机的三位数 变成汉字然后加百位十位
- Java复习笔记(2)——输入、输出和控制流程
- mjpg-streamer学习笔记1----mjpg-streamer移植
- 数字签名– RSA、DSA、ECDSA
- 浅谈ListView之convertView和viewHolder
- React Native有什么优势?能跟原生比么?
- android----popuwindow的使用,自定义的方式
- HTML5之SVG 2D入门9 - 蒙板
- 阿里云CentOS7下mysql5.6安装问题总结
- ERROR 1735 (HY000): Leaf Error (10.130.81.139:3307): Unable to connect to leaf @10.130.81.138:3307 w
- 使用java.util.Properties读取文件
- 5-45 航空公司VIP客户查询 (25分)
- rebar如何stop的?