ViewHolder是什么就不解释了。你们一般怎么写ViewHolder呢? java
ViewHolder holder = null; if(convertView == null) { convertView = mInflater.inflate(R.layout.xxx null); holder = new ViewHolder(); holder.tvXXX = (TextView)findViewById(R.id.xxx); //...一连串的findViewById } else { holder = (ViewHolder) convertView.getTag(); } private static class ViewHolder{ TextView tvXXX; //不少view的定义 }
这么写一次还行,但问题是总有不少不少的ViewAdapter要这么写,每次都repeat,repeat,repeat 累啊。因此,有这么一种简洁的写法分享给你们,先声明,从国外网站上看的,不是本身原创的,但确实很喜欢这个简洁的设计。
ViewHolder这么写(只提供一个静态方法,其实能够加一个私有构造函数防止外部实例化),代码很简单,看过就明白了 git
public class ViewHolder { // I added a generic return type to reduce the casting noise in client code @SuppressWarnings("unchecked") public static <T extends View> T get(View view, int id) { SparseArray<View> viewHolder = (SparseArray<View>) view.getTag(); if (viewHolder == null) { viewHolder = new SparseArray<View>(); view.setTag(viewHolder); } View childView = viewHolder.get(id); if (childView == null) { childView = view.findViewById(id); viewHolder.put(id, childView); } return (T) childView; } }
在getView里这样 github
@Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(context) .inflate(R.layout.banana_phone, parent, false); } ImageView bananaView = ViewHolder.get(convertView, R.id.banana); TextView phoneView = ViewHolder.get(convertView, R.id.phone); BananaPhone bananaPhone = getItem(position); phoneView.setText(bananaPhone.getPhone()); bananaView.setImageResource(bananaPhone.getBanana()); return convertView; }
哈哈,完成了,果断把这个ViewHolder类加入本身的utils,一劳永逸了之后~ 值得注意的是SparseArray这个知识点,优化过的存储integer和object键值对的hashmap,网上资料不少这里就不废话了~ ide
------------------------------------------原帖中的部分评论------------------------------------------------- 函数
#lixiao000013 性能
最简洁的写法是不写ViewHolder 使用SimpleAdapter或者SimpleCursorAdapter 重写 bindView 测试
------------------------------------------------------------------------------- 优化
#zhugogogo 网站
“楼主解释一下,会不会形成内存泄露。。。。。那样的话就没有意思了。。。。” spa
泄露?memory leak? 不会啊,你说的多是oom, out of memory吧?
其实这种写法本质和ViewHolder Partten没有什么不一样,ViewHolder Partten是把一个自定义类绑定到一个view,这种是把SparseArray绑定到一个view,虽然SparseArray 初始化会分配10长度的地址,理论上貌似浪费了内存,理论上插入和删除操做也是有时间损耗的,可是这些都在容许范围内。
好比https://github.com/JoanZapata/base-adapter-helper 做者也说了他作了大量测试,这种损耗微乎其微。
再次,万一万一因特殊状况发现了有性能瓶颈,到时候再优化就能够了,可是绝大多数场合都是可使用的,大量简化你的开发,加快开发速度,代码少了,出错的概率就小了,维护的成本也小了~好处仍是大大的。
https://github.com/JoanZapata/base-adapter-helper 这个项目在我正文贴出的代码基础上进一步封装了许多实用的功能,更cool哦~ 能够下载好好研究一下~
“一、引入了SparseArray,那样的话,列表每一项都多了一个SparseArray,这种集合类型内部成员变量都很 ...”
简单的纸上分析~:
(1)ViewHolder Pattern是每个View一个ViewHolder,里面是记录listitem内控件引用; SparseArray是记录id和控件引用的键值对,固然SparseArray初始化会分配必定地址空间(默认是10),可是这些内存损耗应该是能够忽略的~
(2)SparseArray是优化过的int-object的hashmap,使用折半查找,并优化了内存分配,因此代码执行成本一般是可控的。
综上,使用SparseArray与ViewHolder相比是有损耗,但应该是可控的。使用SparseArray优势是加快开发速度和减小代码维护,当发现有性能瓶颈时,再进行优化~