您的位置:首页 > 移动开发 > Android开发

Android ListView优化

2016-06-04 19:00 417 查看
在Android的控件中,ListView是比较麻烦的一个。也是比较吃内存的(如果item很多的话)。那么有没有什么方式可以优化一下呢?

ListView是可以优化的,但是得先搞明白Adapter才行。不清楚Adapter,就没法说ListView的优化问题。

为此,我们需要自己实现一个继承自BaseAdapter的实现类MyAdapter.

参考文章:http://mobile.51cto.com/abased-445617.htm

这里先提出可以优化的点:

1、利用Android的Recycle机制,只去实例化必要的View对象。
2、利用Android提供的ViewHolder对象,避免findViewById()这个方法的重复调用。
3、监听ListView的滚动事件,根据情况,合理加载数据。
解释:
      不管是什么屏幕,长和宽是一定的,每一屏能显示的ListView的项(item)是有限的,假设最大能显示item_n。那么当屏幕向上滑动时,新的item_(n+1)在底部出现必然伴随最上面一个item_0的不可见。那么那个不可见的item怎么处理呢?肯定不会直接销毁掉,那多浪费资源啊,直接把item_0的View给item_(n+1)用不就是一种理想状态吗?这就是Android的Recycle机制。

      接着上面的讲,既然item_(n+1)的View是item_0的,那么View中包含的各种控件也肯定是存在的,那item_0干嘛不把控件对象也一起给item_(n+1)呢,好人做到底嘛。其实View对象中有一个成员viewHolder,这里面是可以存储控件对象的。那么item_(n+1)在拿到View的时候,直接去访问View的viewHolder对象,就拿到item_0的控件对象了。这样item_(n+1)就少了findViewById()这个方法的调用。

     由以上两步,就实现了View对象的最小量创建。同时实现了各控件只获取一次(对已同一个View)的操作。这样就避免了很多重复性质的操作。

     同时在用户使用时,可能手指是滑得很快的,对于那些一闪而过的item_x,我们有必要重视它吗?基本没必要,用户都不关心,我们瞎操心个什么蛋。对于这些一闪而过的item,像一些网上的图片资源是显然没必要加载的,拖延反应速度不说,关键还浪费流量。所以说,在用户快速滚动时,我们只需要对不确定的item_x只加载必要的数据就行了。

解释完了,上代码看一下。

先看下Android2.3的源码--SimpleAdapter.java

public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}

private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);
} else {
v = convertView;
}

bindView(position, v);

return v;
}
其中convertView就是那个回收循环使用的View,第一屏的item在创建时convertView是null,当屏幕滑动后convertView就是Android的Recycle机制回收的View.从Android2.3中SimpleAdapter.java的代码中可以看出,android源码其实也是使用了Android的Recycle回收机制的。

下面贴一下自己的代码:

@Override
public View getView(int position, View continer, ViewGroup arg2) {
ViewHolder holder;
if(continer == null){
continer = inflater.inflate(R.layout.array_item, null);
holder = new ViewHolder();
holder.imageView = (ImageView) continer.findViewById(R.id.img);
holder.title_tv = (TextView) continer.findViewById(R.id.title);
holder.content_tv = (TextView) continer.findViewById(R.id.content);
continer.setTag(holder);
}else{
holder = (ViewHolder) continer.getTag();
}
holder.imageView.setBackgroundResource(itemList.get(position).img_id);
holder.title_tv.setText(itemList.get(position).title);
holder.content_tv.setText(itemList.get(position).content);
return continer;
}

class ViewHolder{
public ImageView imageView;
public TextView title_tv;
public TextView content_tv;
}

    从代码中可以看出,这里已经使用了ViewHolder,这就避免了每次都去通过findViewById()来获取控件对象。

     至于第三点的优化,则只需要监听滚动事件,在滚动停止的时候再去加载全部数据,在滚动过程中只加载不要的简单数据,这里就不贴代码了。

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息