天天看点

ListView和GridView列表滑动卡顿问题的优化方法汇总1. 使用ViewHolder2. getView方法中不要进行耗时操作3. 图片的加载采用三级缓存的方式实现4. 列表在滑动过程中不加载,停止时才加载5. 压缩图片大小6. 开启硬件加速7. 其他细节改善

ListView和GridView列表在滑动时出现卡顿现象困扰了很多开发者,下面我们来总结一下优化方案:

1. 使用ViewHolder

在adapter的getView方法中对convertView setTag(viewHolder),这个是大部分开发者都会去用的方案,它的原理是避免重复通过inflate方法去渲染UI,只要set了tag,view就可以被重用,这里不做详细赘述了。

2. getView方法中不要进行耗时操作

比如我们可能需要在getView中加载bitmap,而这是一个耗时的操作,需要用异步的方式去处理(最好是通过线程池,它可以避免由于频繁创建和销毁线程所带来的系统开销,关于线程池的原理和使用可以参考博客http://blog.csdn.net/whsdu929/article/details/52516809)。

3. 图片的加载采用三级缓存的方式实现

加载网络图片时,应先尝试从内存缓存中获取,如果没有再从硬盘缓存(文件缓存)获取,还是没有才会从网络中下载。其实不只是图片,所有文件都可以通过三级缓存方式来加快加载速度避免重复从网络中下载。关于内存缓存和硬盘缓存的实现,可以参考博客http://blog.csdn.net/whsdu929/article/details/52672746。

4. 列表在滑动过程中不加载,停止时才加载

listView.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
            mIsScroll = false;
        }else{
            mIsScroll = true;
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }
});
           

然后在getView中进行判断,只有当mIsScroll为false时才去执行加载图片等异步操作。这里可以根据自己的需要去设置判断条件,除了SCROLL_STATE_IDLE以外,OnScrollListener还要两种状态:SCROLL_STATE_TOUCH_SCROLL(手指在屏幕上滑动)和SCROLL_STATE_FLING(手指离开屏幕之后的惯性滑动)。

5. 压缩图片大小

使用BitmapFactory加载bitmap时,由于会按图片的原始像素分配内存,所以极易发生内存泄漏。可以通过BitmapFactory.Options来压缩图片,改变它的采样率,具体的原理和编码方式可参考博客:http://blog.csdn.net/whsdu929/article/details/52524439

6. 开启硬件加速

可以设置activity的属性:android:hardwareAccelerated=”true”以开启硬件加速。

7. 其他细节改善

(1) ListView、GridView高度设置为match_parent

(2) 实行分页加载,可使用开源的Android-PullToRefresh库,源码地址:https://github.com/chrisbanes/Android-PullToRefresh

(3) 可使用support-v7包下的RecyclerView代替ListView和GridView,它本身已经做好了对view的回收和复用,并且可以轻松实现列表项水平排列、瀑布流、插入删除item时的动画效果等。

继续阅读