RecyclerView源码草析

来源:互联网 发布:unity3d 百度地图 编辑:程序博客网 时间:2024/04/29 23:55

不得不说,看源码使人成长,哈哈哈哈哈。
主要是对onCreateViewHolder这个方法

public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

里面的参数parent的来源不熟悉、不知道是什么鬼。于是就去看源码。首先看这个方法的注释

        /**         * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent         * an item.         * <p>         * This new ViewHolder should be constructed with a new View that can represent the items         * of the given type. You can either create a new View manually or inflate it from an XML         * layout file.         * <p>         * The new ViewHolder will be used to display items of the adapter using         * {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display         * different items in the data set, it is a good idea to cache references to sub views of         * the View to avoid unnecessary {@link View#findViewById(int)} calls.         *         * @param parent The ViewGroup into which the new View will be added after it is bound to         *               an adapter position.         * @param viewType The view type of the new View.         *         * @return A new ViewHolder that holds a View of the given view type.         * @see #getItemViewType(int)         * @see #onBindViewHolder(ViewHolder, int)         */

可以看到

@param parent:The ViewGroup into which the new View will be added after it is bound to an adapter position

翻译一下,就是说新视图被绑定到适配器的具体位置上时,就会被添加到ViewGroup,大家也知道ViewGroup就是一个View的集合嘛,嘿嘿,不过这个注释看是看懂了,但是没有任何帮助啊,还是不知道这个parent具体是个什么玩意。
于是再接着看。

        public final VH createViewHolder(ViewGroup parent, int viewType) {            TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG);            final VH holder = onCreateViewHolder(parent, viewType);            holder.mItemViewType = viewType;            TraceCompat.endSection();            return holder;        }

哎,我们找到了这个方法。然后看到了好东西。

final VH holder = onCreateViewHolder(parent, viewType);

哈哈,看到了吧。onCreateViewHolder(parent, viewType)参数里的parent就是createViewHolder(ViewGroup parent, int viewType)里的parent

public final VH createViewHolder(ViewGroup parent, int viewType)又是在哪被调用的呢,因为到这里,还是不知道parent具体是什么。

再接着找,找到了这个

    if(holder==null){        holder = mAdapter.createViewHolder(RecyclerView.this, type);        if (DEBUG) {            Log.d(TAG, "getViewForPosition created new ViewHolder");        }    }

终于看到正主了。

holder = mAdapter.createViewHolder(RecyclerView.this, type);

这个就是我们要找的东西,原来parent就是RecyclerView.this啊。

那这个mAdapter又是什么鬼呢?大家还记得我们ListView的常用方法把?setAdapter(),然后传一个Adapter进去。OK,我们就按这个思路找,找setAdapter方法。

    public void setAdapter(Adapter adapter) {        // bail out if layout is frozen        setLayoutFrozen(false);        setAdapterInternal(adapter, false, true);        requestLayout();    }

看到了这个setAdapterInternal(adapter, false, true);
setAdapter传进来的Adapter又被传进了setAdapterInternal(adapter, false, true);,好,我们再看看这个方法。不过这个方法比较长,就看关键的地方就好了。

mAdapter = adapter;

这个就是关键。我们传进来的Adapter变成了RecyclerView自己的Adapter。好了。这下逻辑都理清了。
首先是RecyclerView.setAdapter( ),传进去一个Adapter,然后传进去的Adapter被赋值给了RecyclerView内部的Adapter,即mAdapter,然后mAdapter调用createViewHolder方法,传入RecyclerView.this。

holder = mAdapter.createViewHolder(RecyclerView.this, type);

传进来的RecyclerView.this就作为parent。在createViewHolder方法内部。

        public final VH createViewHolder(ViewGroup parent, int viewType) {            TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG);            final VH holder = onCreateViewHolder(parent, viewType);            holder.mItemViewType = viewType;            TraceCompat.endSection();            return holder;        }

这个parent又被传给了onCreateViewHolder方法。

 final VH holder = onCreateViewHolder(parent, viewType);
0 0