职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 402|回复: 9

善意的谎言: AdapterView、Adapter优化

[复制链接]
ksdal 发表于 2011-7-26 09:29 | 显示全部楼层 |阅读模式
我们觉得ListView卡卡的时候就会自然的去寻找优化大法,LZ也一样。一方面拼命优化view的结构一方面另外找到了这么一个广为流传的 ViewHolder、ViewCache办法:

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.topic_list, null);
holder.title = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
}

public class ViewHolder {
public TextView getTitle() {
if (title == null) {
title = (TextView) baseView.findViewById(R.id.title);
}
return title;
}
}
大概思想是setTag();getTag();来保存已经加载过了的 ViewHolder 组件,现在我称ViewHolder  为ABCD 意为毫无特殊意义的类,顶多用到了单例的思想
但是我觉得这些都是毫无意义的, 用tag来保存ViewHolder 这个属于耍小聪明的意思,曲解了tag的本意。另外整个代码并没有真正达到需要的要求

Listview的展现可以看成是分页,系统会加载第一页 我们从写getView 的时候convertView是null 可以看成是第一页的样式没有被初始化。
这个时候我们
holder = new ViewHolder(); convertView = inflater.inflate(R.layout.topic_list, null);
holder.title = (TextView) convertView.findViewById(R.id.title);
开始进行初始化的工作,”第二页“之后这些不必再进行,所以 我认为网上所说的优化指的就是减少“第一页”之后的View创建。这个确实是不错。
但是这种优化没有实质上的改进,有时候我在想为什么全部加载完毕listView回拉还会调用getView()把我的一些初始化代码再来一遍?这个显然是不合理的,而且
不仅仅是初始化问题,一个listView之所以卡主要原因在于来回的进行逻辑操作,例如:listView里面有imageview 而且里面的image是从网络上的,而且你没有存到本地
之类的处理,而且显示出来的时候还要根据width来控制整张图片的尺寸进行缩放,加载listview不可避免的需要做这些操作也就算了,如果已经加载过了这些数据
在来回拖拽的时候也要再操作一遍就会令人无法忍受!
怎么去优化?一方面,我们知道了第一页之后不必要再new 新的View出来,另外一方面我们知道了最重要的是View的内容部能来回、重复初始化。
个人觉得android里面应该有这样的“属性”或者“设置” 让每一项加载过之后不需要再加载直接使用”缓存“的数据。
但是我没有发现这种“设置”,于是我在Adapter 里面用一个HashMap<Integer, View> 储存对应的View
HashMap<Integer, View> m = new HashMap<Integer, View>();


public View getView(int position, View view, ViewGroup parent) {

View convertView = m.get(position);
if (convertView != null) {
return convertView;
} else {
convertView = inflater.inflate(R.layout.topic_list, null);
TextView title = (TextView) convertView
.findViewById(R.id.title);
                        m.put(position, convertView);
                     }
}

暂时就这样了,潜在的问题和其他优化没有细想,成果是 20行带较大的图片的listView来回拖拽毫无压力。

秋秋 发表于 2011-7-26 09:29 | 显示全部楼层
欢迎各位讨论、反驳、完善。。。。。。。。。

北大青鸟 发表于 2011-7-26 09:29 | 显示全部楼层
我也有同感,不过最好需要测试数据比较好一点,因为那个来说GOOGLE IO的优化方法里面有测试数据。

实际上setTag会增加系统的开销,还要多一个静态内部类,即使是优化也是空间换时间的做法,应该有个权衡。

能文能武 发表于 2011-7-26 09:29 | 显示全部楼层
我只能说,业务类越复杂 效果越明显。

愚人 发表于 2011-7-26 09:29 | 显示全部楼层
还是分层比较好,可能用习惯J2EE开发模式吧  

无处不在 发表于 2011-7-26 09:30 | 显示全部楼层
把费事的操作放到异步里不是更好吗?比如图片加载,网络数据读取什么的?

走失的猫咪 发表于 2011-7-26 09:30 | 显示全部楼层
myth2loki
把费事的操作放到异步里不是更好吗?比如图片加载,网络数据读取什么的?


。。。有人告诉过你 我没有用异步操作?

芷馨 发表于 2011-7-26 09:30 | 显示全部楼层
核心提示,listView的item都加载完毕往回拉是否停顿,如果有停顿说明没有写好。
因为加载过了的不需要再加载,除了特别业务处理

能文能武 发表于 2011-7-26 09:30 | 显示全部楼层
有个问题请教楼主,如果数据很多HashMap里是不是会越来越大呢,假设有200个item,HashMap就要存200个View,如果更多呢

fl 发表于 2011-7-26 09:30 | 显示全部楼层
常思己过
有个问题请教楼主,如果数据很多HashMap里是不是会越来越大呢,假设有200个item,HashMap就要存200个View,如果更多呢


。。。这是一种必然。。你这么问 就像既想适用Map保存又不想用map保存一样。

一个adapter 加载的时候不会有任何不一样,用map保存就是对付回拉的时候

至于200个map装不装的了 自己看着办吧


您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-30 04:04 , Processed in 0.141065 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表