IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 关于RecyclerView的Adapter的notifyItemInserted()的一些分析 -> 正文阅读

[移动开发]关于RecyclerView的Adapter的notifyItemInserted()的一些分析

public final void notifyItemInserted(int position) {

mObservable.notifyItemRangeInserted(position, 1);

}

那这个mObservable到底是什么东西呢?阅读Adapter里面的代码可知,它是里面的一个成员变量,继承于Observable

public static abstract class Adapter<VH extends ViewHolder> {

private final AdapterDataObservable mObservable = new AdapterDataObservable();


}

我们先来看Observable里面的代码,我们知道这是一个典型的观察者模式的实现。

如果对观察者模式还不了解的,建议先阅读这篇文章:观察者设计模式 Vs 事件委托(java)

public abstract class Observable<T> {

_/**

  • The list of observers. An observer can be in the list at most

  • once and will never be null.

*/_

protected final ArrayList mObservers = new ArrayList();

_/**

  • Adds an observer to the list. The observer cannot be null and it must not already

  • be registered.

  • @param observer the observer to register

  • @throws IllegalArgumentException the observer is null

  • @throws IllegalStateException the observer is already registered

*/_

public void registerObserver(T observer) {

if (observer == null) {

throw new IllegalArgumentException(“The observer is null.”);

}

synchronized(mObservers) {

if (mObservers.contains(observer)) {

throw new IllegalStateException(“Observer " + observer + " is already registered.”);

}

mObservers.add(observer);

}

}

_/

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

**

  • Removes a previously registered observer. The observer must not be null and it

  • must already have been registered.

  • @param observer the observer to unregister

  • @throws IllegalArgumentException the observer is null

  • @throws IllegalStateException the observer is not yet registered

*/_

public void unregisterObserver(T observer) {

if (observer == null) {

throw new IllegalArgumentException(“The observer is null.”);

}

synchronized(mObservers) {

int index = mObservers.indexOf(observer);

if (index == -1) {

throw new IllegalStateException(“Observer " + observer + " was not registered.”);

}

mObservers.remove(index);

}

}

_/**

  • Remove all registered observers.

*/_

public void unregisterAll() {

synchronized(mObservers) {

mObservers.clear();

}

}

}

接着我们来看这个mObservable是在什么时候初始化的呢,我们回到setAdapter()这个方法

public void setAdapter(Adapter adapter) {

// bail out if layout is frozen

setLayoutFrozen(false);

setAdapterInternal(adapter, false, true);

requestLayout();

}

private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,

boolean removeAndRecycleViews) {

if (mAdapter != null) {

mAdapter.unregisterAdapterDataObserver(mObserver);

mAdapter.onDetachedFromRecyclerView(this);

}

if (!compatibleWithPrevious || removeAndRecycleViews) {

// end all running animations

if (mItemAnimator != null) {

mItemAnimator.endAnimations();

}

// Since animations are ended, mLayout.children should be equal to

// recyclerView.children. This may not be true if item animator’s end does not work as

// expected. (e.g. not release children instantly). It is safer to use mLayout’s child

// count.

if (mLayout != null) {

mLayout.removeAndRecycleAllViews(mRecycler);

mLayout.removeAndRecycleScrapInt(mRecycler);

}

// we should clear it here before adapters are swapped to ensure correct callbacks.

mRecycler.clear();

}

mAdapterHelper.reset();

final Adapter oldAdapter = mAdapter;

mAdapter = adapter;

if (adapter != null) {

adapter.registerAdapterDataObserver(mObserver);

adapter.onAttachedToRecyclerView(this);

}

if (mLayout != null) {

mLayout.onAdapterChanged(oldAdapter, mAdapter);

}

mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);

mState.mStructureChanged = true;

markKnownViewsInvalid();

}

在setAdapterInternal里面主要逻辑就是判断apdter是否为空,不为空的话调用mAdapter.unregisterAdapterDataObserver(mObserver);反注销掉mObserver 接着再调用adapter.registerAdapterDataObserver(mObserver); adapter.onAttachedToRecyclerView(this); 重新注册mObserver和依附到recycleView中。

确定了AdapterDataObservable这个类是什么时候初始化以后,接着我们再回到AdapterDataObservable 这个类

static class AdapterDataObservable extends Observable {

public boolean hasObservers() {

return !mObservers.isEmpty();

}

public void notifyChanged() {

// since onChanged() is implemented by the app, it could do anything, including

// removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

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) {

// since onItemRangeChanged() is implemented by the app, it could do anything, including

// removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

for (int i = mObservers.size() - 1; i >= 0; i–) {

mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);

}

}

public void notifyItemRangeInserted(int positionStart, int itemCount) {

// since onItemRangeInserted() is implemented by the app, it could do anything,

// including removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

for (int i = mObservers.size() - 1; i >= 0; i–) {

mObservers.get(i).onItemRangeInserted(positionStart, itemCount);

}

}

public void notifyItemRangeRemoved(int positionStart, int itemCount) {

// since onItemRangeRemoved() is implemented by the app, it could do anything, including

// removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

for (int i = mObservers.size() - 1; i >= 0; i–) {

mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);

}

}

public void notifyItemMoved(int fromPosition, int toPosition) {

for (int i = mObservers.size() - 1; i >= 0; i–) {

mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);

}

}

}

阅读了这个类的源码以后,我们惊喜地发现,这个类里面的notify方法是不是跟adapter里面的notify方法很相似,让我们来看看这个类里面的notify方法具体做了什么? 以insert为例。

public final void notifyItemInserted(int position) {

mObservable.notifyItemRangeInserted(position, 1);

}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:24:43  更:2021-12-15 18:25:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:43:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码