目录介绍
- 25.0.0.0 请说一下RecyclerView?adapter的作用是什么,几个方法是做什么用的?如何理解adapter订阅者模式?
- 25.0.0.1 ViewHolder的作用是什么?如何理解ViewHolder的复用?什么时候停止调用onCreateViewHolder?
- 25.0.0.2 ViewHolder封装如何对findViewById优化?ViewHolder中为何使用SparseArray替代HashMap存储viewId?
- 25.0.0.3 LayoutManager作用是什么?LayoutManager样式有哪些?setLayoutManager源码里做了什么?
- 25.0.0.4 SnapHelper主要是做什么用的?SnapHelper是怎么实现支持RecyclerView的对齐方式?
- 25.0.0.5 SpanSizeLookup的作用是干什么的?SpanSizeLookup如何使用?SpanSizeLookup实现原理如何理解?
- 25.0.0.6 ItemDecoration的用途是什么?自定义ItemDecoration有哪些重写方法?分析一下addItemDecoration()源码?
- 25.0.0.7 上拉加载更多的功能是如何做的?添加滚动监听事件需要注意什么问题?网格布局上拉加载如何优化?
- 25.0.0.8 RecyclerView绘制原理如何理解?性能优化本质是什么?RecyclerView绘制原理过程大概是怎样的?
- 25.0.0.9 RecyclerView的Recyler是如何实现ViewHolder的缓存?如何理解recyclerView三级缓存是如何实现的?
- 25.0.1.0 屏幕滑动(状态是item状态可见,不可见,即将可见变化)时三级缓存是如何理解的?adapter中的几个方法是如何变化?
- 25.0.1.1 SnapHelper有哪些重要的方法,其作用就是是什么?LinearSnapHelper中是如何实现滚动停止的?
- 25.0.1.2 LinearSnapHelper代码中calculateDistanceToFinalSnap作用是什么?那么out[0]和out[1]分别指什么?
- 25.0.1.3 如何实现可以设置分割线的颜色,宽度,以及到左右两边的宽度间距的自定义分割线,说一下思路?
- 25.0.1.4 如何实现复杂type首页需求?如果不封装会出现什么问题和弊端?如何提高代码的简便性和高效性?
- 25.0.1.5 关于item条目点击事件在onCreateViewHolder中写和在onBindViewHolder中写有何区别?如何优化?
- 25.0.1.6 RecyclerView滑动卡顿原因有哪些?如何解决嵌套布局滑动冲突?如何解决RecyclerView实现画廊卡顿?
- 25.0.1.7 RecyclerView常见的优化有哪些?实际开发中都是怎么做的,优化前后对比性能上有何提升?
- 25.0.1.8 如何解决RecyclerView嵌套RecyclerView条目自动上滚的Bug?如何解决ScrollView嵌套RecyclerView滑动冲突?
- 25.0.1.9 如何处理ViewPager嵌套水平RecyclerView横向滑动到底后不滑动ViewPager?如何解决RecyclerView使用Glide加载图片导致图片错乱问题?
给自己相个亲
- 个人相亲信息:juejin.im/post/684490…
系列博客
- 00.RecyclerView复杂封装库
- 几乎融合了该系列博客中绝大部分的知识点,欢迎一遍看博客一遍实践,一步步从简单实现功能强大的库
- 01.RecyclerView
- RecycleView的结构,RecyclerView简单用法介绍
- 02.Adapter
- RecyclerView.Adapter扮演的角色,一般常用的重写方法说明,数据变更通知之观察者模式,查看.notifyChanged();源码
- 03.ViewHolder
- ViewHolder的作用,如何理解对于ViewHolder对象的数量“够用”之后就停止调用onCreateViewHolder方法,ViewHolder简单封装
- 04.LayoutManager
- LayoutManager作用是什么?setLayoutManager源码分析
- 05.SnapHelper
- SnapHelper作用,什么是Fling操作 ,SnapHelper类重要的方法,
- 06.ItemTouchHelper
- 07.SpanSizeLookup
- SpanSizeLookup如何使用,同时包含列表,2列的网格,3列的网格如何优雅实现?
- 08.ItemDecoration
- ItemDecoration的用途,addItemDecoration()源码分析
- 09.RecycledViewPool
- RecyclerViewPool用于多个RecyclerView之间共享View。
- 10.ItemAnimator
- 官方有一个默认Item动画类DafaultItemAnimator,其中DefaultItemAnimator继承了SimpleItemAnimator,在继承了RecyclerView.ItemAnimator,它是如何实现动画呢?
- 11.RecyclerView上拉加载
- 添加recyclerView的滑动事件,上拉加载分页数据,设置上拉加载的底部footer布局,显示和隐藏footer布局
- 12.RecyclerView缓存原理
- RecyclerView做性能优化要说复杂也复杂,比如说布局优化,缓存,预加载,复用池,刷新数据等等
- 13.SnapHelper源码分析
- SnapHelper旨在支持RecyclerView的对齐方式,也就是通过计算对齐RecyclerView中TargetView 的指定点或者容器中的任何像素点。
- 16.自定义SnapHelper
- 自定义SnapHelper
- 18.ItemTouchHelper 实现交互动画
- 需要自定义类实现ItemTouchHelper.Callback类
- 19.自定义ItemDecoration分割线
- 需要自定义类实现RecyclerView.ItemDecoration类,并选择重写合适方法
- 21.RecyclerView优化处理
- RecyclerView滑动卡顿原因有哪些?如何解决嵌套布局滑动冲突?如何解决RecyclerView实现画廊卡顿?
- 22.RecyclerView问题汇总
- getLayoutPosition()和getAdapterPosition()的区别
- 23.RecyclerView滑动冲突
- 01.如何判断RecyclerView控件滑动到顶部和底部
- 02.RecyclerView嵌套RecyclerView 条目自动上滚的Bug
- 03.ScrollView嵌套RecyclerView滑动冲突
- 04.ViewPager嵌套水平RecyclerView横向滑动到底后不滑动ViewPager
- 05.RecyclerView嵌套RecyclerView的滑动冲突问题
- 06.RecyclerView使用Glide加载图片导致图片错乱问题解决
- 24.ScrollView嵌套RecyclerView问题
- 要实现在NestedScrollView中嵌入一个或多个RecyclerView,会出现滑动冲突,焦点抢占,显示不全等。如何处理?
- 25.RecyclerView封装库和综合案例
- 自定义支持上拉加载更多【加载中,加载失败[比如没有更多数据],加载异常[无网络],加载成功等多种状态】,下拉刷新,可以实现复杂的状态页面,支持自由切换状态【加载中,加载成功,加载失败,没网络等状态】的控件,拓展功能[支持长按拖拽,侧滑删除]可以选择性添加。具体使用方法,可以直接参考demo案例。
25.0.0.0 请说一下RecyclerView?adapter的作用是什么,几个方法是做什么用的?如何理解adapter订阅者模式?
-
关于RecyclerView,大家都已经很熟悉了,用途十分广泛,大概结构如下所示
- RecyclerView.Adapter - 处理数据集合并负责绑定视图
- ViewHolder - 持有所有的用于绑定数据或者需要操作的View
- LayoutManager - 负责摆放视图等相关操作
- ItemDecoration - 负责绘制Item附近的分割线
- ItemAnimator - 为Item的一般操作添加动画效果,如,增删条目等
-
如图所示,直观展示结构
-
adapter的作用是什么
- RecyclerView.Adapter扮演的角色
- 一是,根据不同ViewType创建与之相应的的Item-Layout
- 二是,访问数据集合并将数据绑定到正确的View上
-
几个方法是做什么用的
- 一般常用的重写方法有以下这么几个:博客
public VH onCreateViewHolder(ViewGroup parent, int viewType) 创建Item视图,并返回相应的ViewHolder public void onBindViewHolder(VH holder, int position) 绑定数据到正确的Item视图上。 public int getItemCount() 返回该Adapter所持有的Itme数量 public int getItemViewType(int position) 用来获取当前项Item(position参数)是哪种类型的布局
-
如何理解adapter订阅者模式
-
当时据集合发生改变时,我们通过调用.notifyDataSetChanged(),来刷新列表,因为这样做会触发列表的重绘。
-
注意这里需要理解什么是订阅者模式……
-
a.首先看.notifyDataSetChanged()源码```
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
} -
b.接着查看.notifyChanged();源码
- 被观察者AdapterDataObservable,内部持有观察者AdapterDataObserver集合
static class AdapterDataObservable extends Observable<AdapterDataObserver> { public boolean hasObservers() { return !mObservers.isEmpty(); } public void notifyChanged() { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } public void notifyItemRangeChanged(int positionStart, int itemCount) { notifyItemRangeChanged(positionStart, itemCount, null); } public void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload); } } public void notifyItemRangeInserted(int positionStart, int itemCount) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onItemRangeInserted(positionStart, itemCount); } } }
- 观察者AdapterDataObserver,具体实现为RecyclerViewDataObserver,当数据源发生变更时,及时响应界面变化
public static abstract class AdapterDataObserver { public void onChanged() { // Do nothing } public void onItemRangeChanged(int positionStart, int itemCount) { // do nothing } public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { onItemRangeChanged(positionStart, itemCount); } }
-
c.接着查看setAdapter()源码中的setAdapterInternal(adapter, false, true)方法
- setAdapter源码博客
public void setAdapter(Adapter adapter) { // bail out if layout is frozen setLayoutFrozen(false); setAdapterInternal(adapter, false, true); requestLayout(); }
- setAdapterInternal(adapter, false, true)源码
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious, boolean removeAndRecycleViews) { if (mAdapter != null) { mAdapter.unregisterAdapterDataObserver(mObserver); mAdapter.onDetachedFromRecyclerView(this); } if (!compatibleWithPrevious || removeAndRecycleViews) { removeAndRecycleViews(); } mAdapterHelper.reset(); final Adapter oldAdapter = mAdapter; mAdapter = adapter; if (adapter != null) { //注册一个观察者RecyclerViewDataObserver adapter.registerAdapterDataObserver(mObserver); adapter.onAttachedToRecyclerView(this); } if (mLayout != null) { mLayout.onAdapterChanged(oldAdapter, mAdapter); } mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious); mState.mStructureChanged = true; markKnownViewsInvalid(); }
-
d.notify……方法被调用,刷新数据
- 当数据变更时,调用notify**方法时,Adapter内部的被观察者会遍历通知已经注册的观察者的对应方法,这时界面就会响应变更。博客
-
25.0.0.1 ViewHolder的作用是什么?如何理解ViewHolder的复用?什么时候停止调用onCreateViewHolder?
-
ViewHolder作用大概有这些:
- adapter应当拥有ViewHolder的子类,并且ViewHolder内部应当存储一些子view,避免时间代价很大的findViewById操作
- 其RecyclerView内部定义的ViewHolder类包含很多复杂的属性,内部使用场景也有很多,而我们经常使用的也就是onCreateViewHolder()方法和onBindV