ListView的优化技巧

ListView 的优化技巧

  • ListView的优化可以说是面试必问的,现献上慕课上的很好的视频:
    ListView优化

本篇博客目的看了群英传后,结合书中第4章的总价与视频中的优化技巧,总结下ListView中的常用优化技巧。


  1. 使用ViewHolder模式提高效率

    ViewHolder模式是提高ListView效率的一个很重要的方法。它充分利用ListVIew的缓存机制,避免每次在getView()的时候findViewById操作(findViewById是挺耗时的操作)。据测试,使用ViewHolder将提高50%以上的效率。本篇的目的在于总结,具体的可以参考农民伯伯关于ListView优化的一篇博客

  2. 设置项目分割线

/**
 1. 系统提供了divider和dividerHeight两个属性
 2. 分割线不仅可以设置为一个颜色同样也可以设置为一个图片资源
 **/
android:divider = "@android:color/darker_gray"
android:dividerHeight = "10dp"
3.隐藏ListView的滚动条

默认的ListView在滚动时右边会显示滚动条,只是当前滑动的位置,我们可以设置scrollbars属性来控制滚动条的显示与否。
android:scrollbars = "none"
4.取消ListView的Item点击效果

当点击ListView的一项时,系统会默认出现一个点击效果,但可以通过修改listSelector属性来取消点击后的回馈效果,代码如下:
android:listSelector = "#00000000"
//或者
android:listSelector = "@android:color/transparent"
5.设置ListView需要显示在第几项

ListView以Item为单位来进行显示,默认显示在第一个Item,当需要指定具体显示的Item时可以通过代码来实现。
//N就是需要显示的第NItem
listView.setSelection(N);

//这个方法类似于scrollTo,是瞬间完成的移动。除此之外,还可以使用如下代码来实现平滑移动。
mListView.smoothScrollBy(distance,duration);
mListView.smoothScrollByOffset(offset);
mListVIew.smoothScrollToPosition(index);
6.动态修改ListView
mData.add("new");
mAdapter.notifyDataSetChanged();
7.遍历ListView中所有的Item
for(int i=0;i<mListView.getChildCount();i++){
    View view = mListView.getChildAt(i);
}
8.处理空ListView

ListView用于展示列表数据,但当列表中无数据是,ListView不会显示任何数据或提示,按照完善用户体验的需求,这里应该给以无数据的提示。ListView提供了一个setEmptyView()的方法

<FrameLayout             xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.adnroid.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
<ImageView
    android:id="@+id/empty_view"
    android:src="@mipmap/ic_launcher"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</FramLayout>

在代码中,我们可以通过以下方式给ListView设置空数据时需要显示的布局:

ListView listView = (ListView)findViewById(R.id.listview);
listView.setEmptyView(findViewById(R.id.empty_view));
9.异步加载:耗时的操作放在异步线程中

如果在adapter中的某些操作需要耗费大量的时间,这个时候就要用到异步线程来进行异步就在数据。比如:现在要加载图片,此时我们需要根据url访问网络得到数据,然后将数据解析为Bitmap设置给View。这些操作如果不进行异步处理而直接放入adapter,可想而知,我们的ListView会有多卡。通常有两种实现异步的方式:一种是通过多线程方式通过Handler+Message进行异步加载,另一种是利用android封装好的AsyncTask来实现异步加载。

10.ListView的错位加载问题

具体的情况可以看文章最开始给出的视频中有具体案例。我们先来看看产生这种情况的原因,可以参考这篇博客

http://www.cnblogs.com/lesliefang/p/3619223.html
错位

网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作.
如果不重用 convertView 不会出现错位现象, 重用 convertView 但没有异步操作也不会有问题。
我简单分析一下:
当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView.
当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Item8 复用的是
Item1 的 view 如果没有异步不会有任何问题,虽然 Item8 和 Item1 指向的是同一个 view,但滑到
Item8 时刷上了 Item8 的数据,这时 Item1 的数据和 Item8 是一样的,因为它们指向的是同一块内存,
但 Item1 已滚出了屏幕你看不见。当 Item1 再次可见时这块 view 又涮上了 Item1 的数据。
但当有异步下载时就有问题了,假设 Item1 的图片下载的比较慢,Item8 的图片下载的比较快,你滚上去
使 Item8 可见,这时 Item8 先显示它自己下载的图片没错,但等到 Item1 的图片也下载完时你发现
Item8 的图片也变成了 Item1 的图片,因为它们复用的是同一个 view。 如果 Item1 的图片下载的比
Item8 的图片快, Item1 先刷上自己下载的图片,这时你滑下去,Item8 的图片还没下载完, Item8
会先显示 Item1 的图片,因为它们是同一快内存,当 Item8 自己的图片下载完后 Item8 的图片又刷成
了自己的,你再滑上去使 Item1 可见, Item1 的图片也会和 Item8 的图片是一样的,
因为它们指向的是同一块内存。

(文/mecury(简书作者)
原文链接:http://www.jianshu.com/p/f0408a0f0610
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。)


解决的办法由很多种,这里说一下最简单的一种:使用findViewWithTag
在NewsAdapter中为ImageView设置Tag标识位:

//将url设为imagView的标识位
String urlString = newsBean.newsIconUrl; 
// 将ImageView与url绑定
viewHolder.ivIcon.setTag(urlString); 

然后再加载的过程中通过url来判断对应imagview位置是否一致来决定是否加载。

if (mImageView.getTag().equals(mUrl)) { 
//当url标记和原先设置的一样时,才设置ImageView    
mImageView.setImageBitmap((Bitmap) msg.obj);
}
11.为图片设置缓存

可以利用一些流行的图片加载框架比如Fresco,Glide,Picasso等对Item对应需要显示的图片进行处理,框架中都封装好了对应不同的缓存策略。也可以自己动手实现,利用LruCatche或DiskLruCatche自己实现图片的缓存。具体细节不再多说,可以网上看看比如怎么实现的。

12.ListView的滑动时停止加载和分页加载

先说分页加载,我们不用每次把ListView所有的Item都一次性加载完毕,这样做没必要也很累。我们仅仅需要加载那部分显示在屏幕部分的Item即可,这样所要加载的数据就减少了很多。另一方面,我们需要考虑另一个问题,当用户滑动时,显示在屏幕的Item会不断的变化,如果只是加载显示在屏幕的Item,这也没有必要,因此我们应该在停止滑动时再加载数据

实现步骤:
1.让NewsAdapter实现接口AbsListView.OnScrollListener,并复写里面的方法
2.在复写的方法里面进行一些操作。
@Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        switch (scrollState){
            case SCROLL_STATE_IDLE:  //滑动停止时。
                mImageLoader.loadImages(mStart, mEnd);
                break;
            case SCROLL_STATE_TOUCH_SCROLL: //正在滑动时
                mImageLoader.cancelAllTasks();
                break;
            case SCROLL_STATE_FLING: //手指抛动时,即手指用力滑动在离开后ListView由于惯性而继续滑动

                break;
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mStart = firstVisibleItem;
        mEnd = firstVisibleItem + visibleItemCount;
        //第一次的时候预加载
        if (mFirstIn && visibleItemCount > 0){
            mImageLoader.loadImages(mStart, mEnd);
            mFirstIn = false;
        }
    }

上次面试魅族,在讲ListView优化时记得面试官问了我,怎么获得当前可视Item的位置信息,其实ListView给我们提供了一些封装好了的方法:

//获取可视区域内最后一个Item的id
mListView.getLastVisiblePosition();
//获取可视区域内第一个Item的id
mListView.getFirstVisiblePosition();

说明:文中参考了Android群英传和简书上的这篇文章:
文/mecury(简书作者)
原文链接:http://www.jianshu.com/p/f0408a0f0610
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”
我写此片文章的目的主要是为了整合一些常用的技巧来巩固一下知识,别忘了,很多东西不总结,久了就忘了,以后可能会有继续的更新。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值