ListView
- ListView必须使用ViewHolder模式,ListView有多种item类型的场景,必须对应使用多个ViewHolder,有多个item类型时必须同时复写
@Override
public int getItemViewType(int position) {
}
@Override
public int getViewTypeCount() {
}
这两个方法,才能正确的复用不同类型的convertView。
使用ViewHolder模式时,在getView中使用了convertView.setTag(viewHolder)之后,禁止再次使用convertView.findViewById(R.id.item_content)(这里的R.id.item_content是item布局最顶层的id)得到的view对象去setTag,这会替换掉convertView.setTag(viewHolder)中的viewHolder对象,导致无法复用。(否则会由于convertView中设置的tag被后面的setTag覆盖掉了,导致并没有重用convertView,滑动起来不流畅)。
ListView的android:layout_height属性值必须设置为“match_parent”,并且ListView的父布局的android:layout_height也要设为”match_parent”,以此类推;禁止设置为“wrap_content”,这样会使getview方法重复调用很多次,造成明显的卡顿。
禁止在getView中使用setBackground(alpahColor),setTextColor(alpahColor)等类似的方法直接为控件设置半透明效果,半透明绘制需要大量乘法计算,绘制相对比较耗时,在性能较差的机器上表现的较为明显,如果不需要动态设置透明度,用xml中的属性值设置透明度颜色即可,如果有动态设置listView中元素透明度的需要,可通过以下的做法,对颜色和透明度通过argb的方式合成:
public static int getAlphaColor(int color, float alpha) {
int a = ((int) (alpha * 255)) % 256;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
return Color.argb(a, r, g, b);
}
禁止滥用adapter的notifyDataSetChanged()方法,只应在数据发生改变或状态发生改变需要刷新时才调用notifyDataSetChanged(),因为notifyDataSetChanged()最终会触发requestLayout,引起ListView整个界面的重绘,占用UI线程,如果在滑动切换tab期间调用,会导致滑动动画卡顿。
getView方法中尽量少使用逻辑,禁止在getView方法中多次调用只需使用一次调用结果即可的aidl方法;禁止在getView中进行数据库查询、加载bitmap等较为耗时的操作;一些较为耗时的逻辑判断应该抽离出来,提供setter,getter方法。
禁止在getView中创建大量对象,如直接使用holder.mBtn.setonClickListener(new onClickListenr)…,必须把listener写在getView的外面。
item的布局层级不要过深。布局层级过深会直接导致View的测量与绘制浪费大量的时间,view的个数太多也会增加findViewById的耗时。
备注:未来的选择趋势应该是RecyclerView优于ListView,相比于ListView,RecyclerView的优势在于:
性能更优:默认使用ViewHolder模式;多个RecyclerView可共用一个RecycledViewPool,提供了多级view缓存,更节省内存,提升布局渲染速度、ViewPager滑动流畅度;优化了更新通知方式,可以在视图刷新上采用更加细腻的方法,notifyItemChanged()、notifyItemRemoved()、notifyiteminserted(),ListView在数据改变时只能使用notifyDataSetChanged方法。
更灵活,样式更丰富,方便的动画支持:ListView只支持垂直方向的列表排列,RecyclerView支持水平、垂直和表格列表及其他更复杂的形式,官方默认提供了三种LayoutManager,LinearLayoutManager(线性布局) GridLayoutManager(网格布局)StaggeredGridLayoutManager(瀑布流布局)布局,RecyclerView提供了ItemAnimator,可以方便的在增加或删除Item的时候进行动画。