项目中用到一个内部复杂布局的listview,每个item中都有动态的子item,相当于listview的item中还有listview的样式。刚开始做的思路是,用一个listview,然后item中加个LinearLayout,然后代码动态的生成子item view 添加在其中,希望这样的表述大家能明白,按照这样的思路做好之后发现快速滑动的时候,一卡一顿,实在不能直视,在配置低点的机器上更是不能看。
但是因为赶进度一直没有优化,现在回头看下,虽然已经用了viewHolder但是listview缓冲的机制完全没有发挥作用,因为每个item show的时候都需要removeAll 子item,然后再添加一遍,绘制的时间太长,造成了卡顿。
怎么解决这个问题尼?
刚好google在support v7推出了recyclerView,有着更好的缓存优化机制,我如获救星,赶紧将listview换成了recyclerView,但是效果不尽人意,没有我想象中的效率提升,仔细想了想,recycleView只是针对listView的多type情况做了优化,而实际需求中还是在item中动态的生成item,没有用到recyclerView的优势。
那么自然下面想到的就是干掉动态生成的Item部分,把数据拆分成一个一个的listview item。但是又担心这样的工作量会不会很大,实际抽象过程中发现很容易,就把原来一个model数据拆分成了7个不同类型的model,getView的时候先通过postion 获取当前model的type,然后返回不同的View item,很简单的就把原来只有一种item的listview拆分成了一个有7种类型Item的listView。跑起来之后,速度哗哗的,感觉就更一个item的一样。
listView支持多种类型的Item时候还有个坑:继承BaseAdapter的时候必须复写下面两个方法
//滑动ListView的时候,第一个item消失之后,进入屏幕的item类型必须通过<span style="font-family: Arial, Helvetica, sans-serif;">getItemViewType符合类型才会被复用,否则创建新的item类型,当然这些的前提是你必须使用了listView的缓存tag</span>
@Override public int getItemViewType(int position) { return super.getItemViewType(position); } //默认这个方法返回1,所有有几种类型必须告诉listView,listView就会创建几个不同类型的队列 @Override public int getViewTypeCount() { return super.getViewTypeCount(); }
这个时候,既然动态生成子item的机制已经被干掉了,我又想到了recyclerView,如果用recyclerView会不会比ListView更优尼?说干就干,10分钟我已经完成了替换(思路有了我搬砖的效率还是很快的),跑起来之后,果然唰唰的(其实肉眼已经很难分辨出来和listView的区别了)。但是跟着google走应该不会错,他自己说的:
The RecyclerView
widget
is a more advanced and flexible version of ListView
.
This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerView
widget
when you have data collections whose elements change at runtime based on user action or network events.
希望能帮助到有类似需求的同学:
ListView中有复杂布局,尤其是有动态生成的布局的子布局的,可以考虑一下将原来的Item拆分成不同的类型,然后使用recyclerView。