热门标签 | 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里再看。下回分解~~~


推荐阅读
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 提升Android开发效率:Clean Code的最佳实践与应用
    在Android开发中,提高代码质量和开发效率是至关重要的。本文介绍了如何通过Clean Code的最佳实践来优化Android应用的开发流程。以SQLite数据库操作为例,详细探讨了如何编写高效、可维护的SQL查询语句,并将其结果封装为Java对象。通过遵循这些最佳实践,开发者可以显著提升代码的可读性和可维护性,从而加快开发速度并减少错误。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
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社区 版权所有