【Android面试】Listview和Recyclerview的区别

Listview和Recyclerview的区别(阿里一面,滴滴一面,被问到)

简单比较

listview:实现分割线很简单 ,

    android:divider="@android:color/transparent"
    android:dividerHeight="5dp"

继承重写BaseAdapter类; 自定义ViewHolder与convertView的优化(判断是否为null)

recyclerview: 继承重写RecyclerView.Adapter与RecyclerView.ViewHolder
设置LayoutManager,以及layout的布局效果

布局上

listview:布局比较单一,只支持竖直方向滑动

recyclerview:三种布局

1.线性布局,这个和listview相似 ,实现横向/纵向列表方向的item

LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);

[外链图片转存失败,源站可能有防盗链机 制,建议将图片保失败,源站可能有防盗链机制,建议将图片保存下来直接上传存下来(img-SlsH8lT1-1622017525149)(G:\桌面\image\图像\1621925987945.png)(G:\桌面\image\图像\1621925987945.png)]

2.网格布局,可以指定item的数量。

        mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));//可指定一行item的数目


在这里插入图片描述

3.瀑布流布局,可以指定列表方向,也可以指定同方向的item数量

在这里插入图片描述

局部刷新

1.listview:listview中通常刷新数据 notifyDataSetChanged() ,这种刷新是全局刷新的,每一个item的数据都会重新加载一次,这样很消耗资源,在一些需要频繁更新数据的场景,比如淘宝实时更新的界面,listview实现会很鸡肋

2.recyclerview:可以通过 notifyItemChanged() 来实现局部刷新

ps:不过如果要在ListView实现局部刷新,依然是可以实现的,当一个item数据刷新时,我们可以在Adapter中,实现一个onItemChanged()方法,在方法里面获取到这个item的position(可以通过getFirstVisiblePosition()),然后调用getView()方法来刷新这个item的数据

item view的重用

listview:默认每次加载一个新的item创建一个新view,引起内存增加,不过可以通过判断 convertView 是否为空来重用view。convertView 不为空,则不会产生新的条目, 屏幕上始终是一开始生成的那几个条目

在这里插å¥å›¾ç‰‡æè¿°

recyclerview:默认实现重用view, RecyclerView复用item全部搞定,不需要像ListView那样setTag()与getTag();

ViewHolder

listview:viewHolder需要自定义,如果用getview去获取控件,则每次调用getview都要通过 findViewById 去获取控件, 如果控件个数过多,会严重影响性能 ,因为findViewById相对比较耗时,所以我们需要创建自定义viewHolder,通过getTag和setTag直接获取view

recyclerview:继承recyclerView.ViewHolder,默认需要重写viewHodler,使用已经封装好的

嵌套滑动机制

Android 5.0推出了嵌套滑动机制,在之前,一旦子View处理了触摸事件,父View就没有机会再处理这次的触摸事件,而嵌套滑动机制解决了这个问题,能够实现如下效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSmjvzkB-1622017525151)(G:\桌面\image\图像\20160808135831369)]

为了支持嵌套滑动,子View必须实现NestedScrollingChild接口,父View须实现NestedScrollingParent接口。

img 而RecyclerView实现了NestedScrollingChild接口,而CoordinatorLayout实现了NestedScrollingParent接口,上图是实现CoordinatorLayout嵌套RecyclerView的效果。

listview: ListView 并不支持嵌套滚动机制

img

空数据处理

ListView 提供了 setEmptyView 这个 API 来让我们处理 Adapter 中数据为空的情况

recyclerview没有提供

Listview的二级缓存

RecycleBin:大意就是通过两级缓存来缓存view。

(RecycleBin在layout的过程中便于view重用,RecycleBin有两级存储:ActiveViews和ScrapViews。

ActiveViews存储的是layout开始的时候屏幕上那些view。layout结束后,所有ActiveViews中的view被移动到ScrapViews中。

ScrapViews中的views是那些可能被adapter重新用到的view,以避免重新创建不必要的view。)

ActiveViews

一级缓存,顾名思义活动等view,这些view是布局过程开始屏幕上的view。layout开始时这个数组被填充,layout结束,ActiveViews中的view移动到 ScrapViews。ActiveViews代表了一个连续范围的views,其第一个view的位置存储在FirstActivePosition变量中。

ScrapViews

二级缓存,顾名思义废弃的view,无序的被adapter的convertView使用的view的集合
ScrapViews是多个list组成的数组,数组的长度为viewTypeCount,每个item是个list,所以每个list缓存不同类型item布局的view,所以ScrapViews应该是下图的样子。

Recyclerview的四级缓存

RecycleView的四级缓存是由三个类共同作用完成的,Recycler、RecycledViewPool和ViewCacheExtension。

Recycler

​ 用于管理已经废弃或者与RecyclerView分离的ViewHolder,这里面有两个重要的成员

1.屏幕内缓存 一级缓存,屏幕内缓存指在屏幕中显示的ViewHolder,这些ViewHolder会缓存在AttachedScrap、ChangedScrap中

ChangedScrap —>表示数据已经改变的viewHolder列表

AttachedScrap—>表示未与RecyclerView分离的ViewHolder列表
2.屏幕外缓存 二级缓存,当列表滑动出了屏幕时,ViewHolder会被缓存在 CachedViews ,其大小由ViewCacheMax决定,默认DEFAULT_CACHE_SIZE为2,可通过Recyclerview.setItemViewCacheSize()动态设置。

RecycledViewPool

​ 三级缓存, RecycledViewPool类是用来缓存ViewHolder用,如果多个RecyclerView之间用setRecycledViewPool(RecycledViewPool)设置同一个RecycledViewPool,他们就可以共享ViewHolder。

ViewCacheExtension

​ 四级缓存, 开发者可自定义的一层缓存,是虚拟类ViewCacheExtension的一个实例,开发者可实现方法getViewForPositionAndType(Recycler recycler, int position, int type)来实现自己的缓存。

“要不忘初心,永远谦逊”

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rose J

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值