Android RecyclerView分析 第一篇【ChildHelper】

一、在RecyclerView中的位置与角色

在RecyclerView对象创建时,会创建一个 ChildHelper 对象。
在设置layoutManager时,将 RecyclerView中的成员变量 mChildHelper 传进 layoutManager中。

ChildHelper 封装了对 RecyclerView所有子View的所有操作。包括
子View的添加、删除、绑定、解绑、获取子View、判断是否隐藏等。

在RecyclerView 和 layoutManager中所有的 对子View的操作和查询,全部代理给了 ChildHelper。

二、ChildHelper 数据结构

以一个Bucket链条结构,表示一个RecyclerView中所有 Child 的显示/隐藏 状态。
一个Bucket对象是 64bit 存储,1 代表 child hidden,0代表 child 是正常的。

Bucket1 ------------- Bucket0
(Next) -------------- (this)

mData
long1 --------------long0

Child Index
127–64 ----------- 63–0

方向
After ----- 0 ------Before
1000100 0 10000

三、具体用途

最核心与调用次数多的:

  • 查询某个子View 是否是隐藏状态 boolean isHidden(View view)
  • 取子View个数
    int getChildCount() 获取可见View个数
    int getUnfilteredChildCount() 获取所有子View个数
  • 取某个子View
    View getChildAt(int index) 获取可见View中的index位置的View
    View getUnfilteredChildAt(int index) 获取所有子View中的index位置的View

其他的:

void addView(View child, int index, boolean hidden)
void removeView(View view)
void removeAllViewsUnfiltered()

void attachViewToParent(View child, int index, ViewGroup.LayoutParams layoutParams,
            boolean hidden)
void detachViewFromParent(int index)

int indexOfChild(View child)

void hide(View view)
void unhide(View view)

四、ChildHelper的基本调用逻辑

举例说明:

void addView(View child, int index, boolean hidden) {
		// 第一步:更新Bucket链 数据
        final int offset;
        if (index < 0) {
            offset = mCallback.getChildCount();
        } else {
            offset = getOffset(index);
        }
        mBucket.insert(offset, hidden);
        if (hidden) {
            hideViewInternal(child);
        }
        // 第二步:调用callback,执行真正的操作
        mCallback.addView(child, offset);
        if (DEBUG) {
            Log.d(TAG, "addViewAt " + index + ",h:" + hidden + ", " + this);
        }
    }

这里的 mCallback 是 ChildHelper定义的接口:

interface Callback {
        int getChildCount();
        void addView(View child, int index);
        ... ...
}

接口的定义,在RecyclerView中:

this.mChildHelper = new ChildHelper(new ChildHelper.Callback() {
            public int getChildCount() {
                return RecyclerView.this.getChildCount();
            }

            public void addView(View child, int index) {
                RecyclerView.this.addView(child, index);
                RecyclerView.this.dispatchChildAttached(child);
            }

            public int indexOfChild(View view) {
                return RecyclerView.this.indexOfChild(view);
            }
        ... ...
        }

可见,Callback的具体实现,全是 调了RecyclerView 的方法。

ChildHelper 中的大部分方法,都按上面的逻辑来组织代码的:

  • 第一步:更新Bucket链 数据
  • 第二步:调用callback,调用RecyclerView 执行真正的操作.

你可能感兴趣的:(Android,组件,android,RecyclerView,ChildHelper)