RecyclerView和ListView的区别、RecyclerView优化

一   ListView和RecyclerView区别

 

  •       ListView

        1.Adapter继承的是BaseAdapter。

        2.可以直接在布局中设置分割线。

        3.点击事件自带setOnItemClickListener方法

        4.自带增加头部尾部方法   addHeaderView和addFooterView

        5.ListView只有刷新所有数据的方法,局部刷新需自己定义

        6.没有动画效果

        7.缓存机制原理大致相同(缓存层级不同,获取缓存流程不同)

  • RecyclerView

       1.Adapter继承的是RecyclerView.Adapter

       2.不能在布局中直接设置分割线,可以自定义,在setAdapter之前添加分割线

       3.RecyclerView提供addOnItemTouchListener监听item的触摸事件,通过addOnItemTouchListener加上Gesture Detector来实现item响应方法(也可以自定义方法进行处理)

       4.RecyclerView需要借助Adapter实现头尾布局,通过设置ViewHolder不同的类型实现

       5.RecyclerView可以调用notifyItemChanged实现局部刷新

       6.RecyclerView自带动画效果,如果需要自定义动画可通过自定义RecyclerView.ItemAnimator类,然后调用setItemAnimator设置

       7.缓存机制原理大致相同(缓存层级不同,获取缓存流程不同)

二   RecyclerView 优化

   1.布局优化

       减少层次结构、减少过渡绘制,可以提高item的解析测量与绘制的效率

   2.关闭动画效果

       如果不需要动画效果,可以取消RecyclerView的默认动画      mRecyclerView.setItemAnimator(null);

   3.Item等高

     把所有的 Item 的高度固定大小,这样可以减少测量次数,尤其是对于 GridLayoutManager。

     mRecyclerView.setHasFixedSize(true);

    4.使用getExtraLayoutSpace为LayoutManager设置更多的预留空间

     当item布局内容比较高,屏幕内只能展示一条item或者说一条显示都不全的时候,第一次滑动到第二个元素就会卡顿。

     RecyclerView (以及其他基于adapter的view,比如ListView、GridView等)使用了缓存机制重用子 view(即系统只将屏幕可见范围之内的元素保存在内存中,在滚动的时候不断的重用这些内存中已经存在的view,而不是新建view)。

     这个机制会导致一个问题,启动应用之后,在屏幕可见范围内,如果只有一张卡片可见,当滚动的时 候,RecyclerView找不到可以重用的view了,它将创建一个新的,因此在滑动到第二个feed的时候就会有一定的延时,但是第二个feed之 后的滚动是流畅的,因为这个时候RecyclerView已经有能重用的view了。

   如何解决这个问题呢,其实只需重写getExtraLayoutSpace()方法。根据官方文档的描述 getExtraLayoutSpace将返回LayoutManager应该预留的额外空间(显示范围之外,应该额外缓存的空间)。

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
    @Override
    protected int getExtraLayoutSpace(RecyclerView.State state) {
        return 300;
    }
};

 5.RecycledViewPool

  当多个RecyclerView有相同的item布局结构时,多个RecyclerView共用一个RecycledViewPool可以避免创建ViewHolder的开销,避免GC。RecycledViewPool对象可通过RecyclerView对象获取,也可以自己实现。

 6.避免创建过多对象

   onCreateViewHolder 和 onBindViewHolder 对时间都比较敏感,尽量避免繁琐的操作和循环创建对象。例如创建 OnClickListener,可以全局创建一个,然后数据通过 itemView.setTag 携带。

  7.局部刷新

   可以用一下一些方法,替代notifyDataSetChanged,已达到局部刷新的目的。

notifyItemChanged(int position)

notifyItemInserted(int position)

notifyItemRemoved(int position)

notifyItemMoved(int fromPosition, int toPosition)

notifyItemRangeChanged(int positionStart, int itemCount)

notifyItemRangeInserted(int positionStart, int itemCount)

notifyItemRangeRemoved(int positionStart, int itemCount)

如果必须用 notifyDataSetChanged(),那么最好设置 mAdapter.setHasStableIds(true)

  8.重写onSroll事件

   对于大量图片的RecyclerView,滑动暂停后再加载;RecyclerView中存在几种绘制复杂,占用内存高的楼层类型,但是用户只是快速滑动到底部,并没有必要绘制计算这几种复杂类型,所以也可以考虑对滑动速度,滑动状态进行判断,满足条件后再加载这几种复杂的。

     

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值