热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android中RecyclerView源码解析一(Adapter与RecyclerView是怎么关联的?)

小白也能看懂源码系列第一步先看下面这个普通的抽象类:Observable它其实里面就一个ArrayList,只做了一个add与remove的操作而已。Observable.java

小白也能看懂源码系列

第一步

先看下面这个普通的抽象类:Observable它其实里面就一个ArrayList,只做了一个addremove的操作而已。

Observable.java


public abstract class Observable{
protected final ArrayList mObservers = new ArrayList();
public void registerObserver(T observer) {
//④
mObservers.add(observer);
}
public void unregisterObserver(T observer) {
mObservers.remove(index);
}
public void unregisterAll(T observer) {
mObservers.clear();
}
}
第二步

直接上精简版的RecyclerView

RecyclerView.java

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2 {
Adapter mAdapter;
private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();
public void setAdapter(Adapter adapter) {
setAdapterInternal(adapter, false, true);
}
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious, boolean removeAndRecycleViews) {
if (mAdapter != null) {
mAdapter.unregisterAdapterDataObserver(mObserver);
}
final Adapter oldAdapter = mAdapter;
mAdapter = adapter;
if (adapter != null) {
//①注意参数哈,其实就是RecyclerView里的成员变量RecyclerViewDataObserver mObserver
adapter.registerAdapterDataObserver(mObserver);
}
}
//内部类:AdapterDataObservable
static class AdapterDataObservable extends Observable{
//③其实就是调用的super.registerObserver(RecyclerViewDataObserver mObserver),super就是指第一步那个Observable类
//此时:RecyclerView.mAdapter.mObservable.mObservers.get(0) = mObserver
//mObservers指的是其父类的ArrayList而已
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,@Nullable Object payload) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
}
}
……
}
//内部类:RecyclerViewDataObserver
private class RecyclerViewDataObserver extends AdapterDataObserver {
RecyclerViewDataObserver() {} @Override
public void onChanged() {
mAdapterHelper.hasPendingUpdates();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)
}
……
}
//内部类:Adapter
public abstract static class Adapter {
private final AdapterDataObservable mObservable = new AdapterDataObservable();
public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);
public abstract void onBindViewHolder(@NonNull VH holder, int position);
public abstract int getItemCount();
public int getItemViewType(int position) {
return 0;
}
public long getItemId(int position) {
return NO_ID;
}
public void onViewRecycled(@NonNull VH holder) {
//空实现
}
public void registerAdapterDataObserver(@NonNull AdapterDataObserver observer) {
//②
mObservable.registerObserver(observer);
}
public void unregisterAdapterDataObserver(@NonNull AdapterDataObserver observer) {
mObservable.unregisterObserver(observer);
}
//当用户主动调用这个方法的时候(通常是:yourAdapterWhichExtendsRecyclerViewAdapter.notifyDataSetChanged())
//此时:相当于调用的是mObservable(即: AdapterDataObservable)的notifyChanged()方法。
//而这个方法的作用是:把RecyclerView.mAdapter.mObservable.mObservers里list存放的RecyclerViewDataObserver些循环同时调用其onChanged方法。
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
} ……
}
}
第三步

模拟debug方式一步一步运行。当调用RecyclerView#setAdapter()后的运行步骤如上①②③④所示:在setAdapter的执行完成后就实现了RecyclerView.mAdapter.mObservable.mObservers.get(0) = mObserver,而这个mObserver就是RecyclerView里的成员变量private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver()

当用户手动调用adapter.notifyDataSetChanged()adapter.notifyItemChanged(int position)之类的方法的时候其实就是调用了mObserver里的onChanged()onItemRangeChanged(int positionStart, int itemCount)。而具体的RecyclerView在界面上体现出来的变化则是通过mAdapterHelper.hasPendingUpdates()mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)之类来实现的。具体的得进入到mAdapterHelper里再看。下回分解~~~


推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
author-avatar
手机用户2502902843
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有