RecyclerView的卡顿优化(一)
2016-07-13 16:40
441 查看
对于列表,不管用RecyclerView 还是ListView,我们都会用ViewHolder来复用布局。但是,即使这样做了,还是会出现卡顿。
这时候我们就需要分析卡顿的原因是什么?为什么别人写的不卡?为什么很多商店的app都有卡顿?
卡顿的原因:
1.产品设计不合理导致卡片布局过度复杂,产品只追求界面的高大上,而忽略了实现上的复杂度。
2.卡顿的另一个最大原因是图片的加载,如果图片过大,卡顿甚至崩溃都不是问题。即使图片使用了压缩后的,并且用了Fresco等图片加载框架,发现还是会有卡顿。虽然图片是异步加载的,但是图片的加载都伴随着三级缓存,图片IO会导致卡
经过以上1,2分析,然后就开始考虑该怎么去优化呢?如果产品的需求改变不了,那就要另辟蹊径了。也就是主要的优化集中在复杂布局和图片加载。
复杂布局的优化:
1.尽量减少布局嵌套,层级越深,每次测量时间久越久。
2. 如果布局很复杂,可以考虑自定义布局能不能实现。
3.尽量减少过度绘制区域。这个可以在开发者选项中看到:调试GPU过度绘制。
图片加载的优化,不仅仅是图片加载,应该说是列表在滚动过程中,如果布局很复杂,而且样式也很多,那就需要考虑滚动的时候不做复杂布局及图片的加载,尽量减少滚动过程中的耗时操作,这样滚动停止的时候再加载可见区域的布局,因为这个时候是停止状态,即使略微耗时一些用户的感知也是比较小的,就会给人一种不卡的假象。
对于列表滚动过程中,卡顿的判断可以打开开发者选项中的:GPU呈现模式分析->在屏幕上显示为条形图。就可以直观的看到滑动过程中有没有卡顿了。
先上一些关键代码吧:
主要就是对onScrollStateChanged方法进行监听,然后通知adapter是否加载图片或复杂布局。
对于复杂布局的优化效果还是很明显的。
如果读者有更好的方法,请不吝赐教。
下面是基于此文进行的进一步优化
RecyclerView卡顿优化(二)附源码
这时候我们就需要分析卡顿的原因是什么?为什么别人写的不卡?为什么很多商店的app都有卡顿?
卡顿的原因:
1.产品设计不合理导致卡片布局过度复杂,产品只追求界面的高大上,而忽略了实现上的复杂度。
2.卡顿的另一个最大原因是图片的加载,如果图片过大,卡顿甚至崩溃都不是问题。即使图片使用了压缩后的,并且用了Fresco等图片加载框架,发现还是会有卡顿。虽然图片是异步加载的,但是图片的加载都伴随着三级缓存,图片IO会导致卡
经过以上1,2分析,然后就开始考虑该怎么去优化呢?如果产品的需求改变不了,那就要另辟蹊径了。也就是主要的优化集中在复杂布局和图片加载。
复杂布局的优化:
1.尽量减少布局嵌套,层级越深,每次测量时间久越久。
2. 如果布局很复杂,可以考虑自定义布局能不能实现。
3.尽量减少过度绘制区域。这个可以在开发者选项中看到:调试GPU过度绘制。
图片加载的优化,不仅仅是图片加载,应该说是列表在滚动过程中,如果布局很复杂,而且样式也很多,那就需要考虑滚动的时候不做复杂布局及图片的加载,尽量减少滚动过程中的耗时操作,这样滚动停止的时候再加载可见区域的布局,因为这个时候是停止状态,即使略微耗时一些用户的感知也是比较小的,就会给人一种不卡的假象。
对于列表滚动过程中,卡顿的判断可以打开开发者选项中的:GPU呈现模式分析->在屏幕上显示为条形图。就可以直观的看到滑动过程中有没有卡顿了。
先上一些关键代码吧:
import android.content.Context; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; /** * Created by lk on 16/7/12. */ public class PWRecyclerView extends RecyclerView { private OnScrolledLinstener onScrolledLinstener; private BaseAdapter adapter; private LayoutManager layout; public PWRecyclerView(Context context) { this(context, null); } public PWRecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public PWRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); addOnScrollListener(new ImageAutoLoadScrollListener()); } @Override public void setLayoutManager(LayoutManager layout) { this.layout = layout; super.setLayoutManager(layout); } @Override public void setAdapter(Adapter adapter) { if(adapter instanceof BaseAdapter) { this.adapter = (BaseAdapter) adapter; } super.setAdapter(adapter); } public class ImageAutoLoadScrollListener extends OnScrollListener{ @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if(onScrolledLinstener != null){ onScrolledLinstener.onScrolled(recyclerView, dx, dy); } } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState){ case SCROLL_STATE_IDLE: // The RecyclerView is not currently scrolling. //对于滚动不加载图片的尝试 adapter.setScrolling(false); adapter.notifyDataSetChanged(); break; case SCROLL_STATE_DRAGGING: // The RecyclerView is currently being dragged by outside input such as user touch input. adapter.setScrolling(false); break; case SCROLL_STATE_SETTLING: // The RecyclerView is currently animating to a final position while not under adapter.setScrolling(true); break; } } } public void setOnScrollLinstener(OnScrolledLinstener onScrolledLinstener){ this.onScrolledLinstener = onScrolledLinstener; } public interface OnScrolledLinstener{ void onScrolled(RecyclerView recyclerView, int dx, int dy); } }
主要就是对onScrollStateChanged方法进行监听,然后通知adapter是否加载图片或复杂布局。
对于复杂布局的优化效果还是很明显的。
如果读者有更好的方法,请不吝赐教。
下面是基于此文进行的进一步优化
RecyclerView卡顿优化(二)附源码
相关文章推荐
- Linux grep使用详解
- 【MySQL】性能优化之 Index Condition Pushdown
- iOS-copy与mutableCopy浅析
- java面向对象基础
- Java Swing JTable 表格【16:复选框JCheckBox作为表格元素】
- HTML块级标签汇总(小篇)
- Jcrop使用方法
- eclipse代码颜色设置
- nginx 编译安装
- CSS背景图拉伸自适应尺寸,全浏览器兼容
- Linux 常用命令
- 【TJOI & HEOI 2016】【BZOJ 4556】【JZOJ 4614】 游戏
- Android地位的4大方式
- Android界面编程——导航栏及菜单(六)
- 机器学习(1):基本概念
- 从MVC到前后端分离
- 大型网站架构学习
- uva-10115 - Automatic Editing
- uc/os-iii学习笔记-任务管理
- mysql获取第n条记录