我们经常会遇到 ListView滑动的时候出现卡顿现象,这样我们该如何解决呢?我们可以从以下几个方面进行优化:
1.重用convertView,每次滑动list,view回收,当需要显示新的item时候,可以重用回收器的view。
2.避免在getView中重复调用findViewById,使用静态ViewHolder,然后保存在View的 tag中。
3.利用好View Type,给每个类型创建不同的view有利于listview回收,类型不能太多。
4.尽量让 ItemView 的 Layout 层次结构简单,善用自定义View,自定义 View 可以有效的减小 Layout 的层级,而且对绘制过程可以很好的控制。
5.尽量能保证 Adapter 的 hasStableIds() 返回 true,这样在 notifyDataSetChanged() 的时候,如果 id 不变,ListView 将不会重新绘制这个 View,达到优化的目的。
6.ListView滑动的流畅性,getView()中尽量少做一些耗时的操作,我们可以通过监听ListView滚动事件来使listview处于不同滚动状态做不同做不同的事情,比如处于滚动过程中加载少量数据,处于空闲状态再加载所有数据。
例如ListView经常需要展示图片,如果在滑动时对滑动过的每张图片都要加载,会比较占内存。推荐的优化方法是设置OnScrollListener,在滑动完成后再下载当前页面的图片。
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState){
// 用户手指滑动中
case SCROLL_STATE_TOUCH_SCROLL:
// 用户手指离开,但滑动动画进行中
case SCROLL_STATE_FLING:
break;
// 滑动结束
case SCROLL_STATE_IDLE:
int start = listView.getFirstVisiblePosition();
int end = listView.getLastVisiblePosition();
if(end >= listView.getCount()){
end = listView.getCount() - 1;
}
//展示start-end之间的图片
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
onClickListener,当ListView的item中有比如button这些子view时,需要对其设置onclickListener,通常的写法是在getView方法中一个个设置,比如holder.img.setonClickListener(new onClickListenr)...
但是这种写法每次调用getView时都设置了一个新的onClick事件,效率很低。高效的写法可以直接在ViewHolder中设置一个position,然后viewHolder implements OnClickListenr:
class ViewHolder implements OnClickListener{
int position;
TextView name;
public void setPosition(int position){
this.position = position;
}
@Override
public void onClick(View v) {
switch (v.getId()){
//XXXX
}
}
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.name.setOnClickListener(this);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
//设置holder
holder.name.setText(list.get(position).partname);
//设置position
holder.setPosition(position);
return convertView;
}
参考:http://niorgai.github.io/2014/12/13/ListView%E4%B8%8EBaseAdapter%E4%BC%98%E5%8C%96/