RecycleView 与 Listview 的差别

来源:互联网 发布:ubuntu搜狗输入法异常 编辑:程序博客网 时间:2024/05/22 00:06

先提出一个问题 在listView绘制完成后 从contentView中能findViewById到item里面的view么?
答案是:肯定的

要是你很明确的知道这个问题的,那就不用看了 哈哈

先阐述下我为什么会发现这个问题呢?就是利用ButterKnife是发现的一个问题。

问题的引入

ButterKnife+ListView 这个我在加头的时候是可以的利用ButterKnife可以找到头里面的id的

ButterKnife+RecycleView 这个我在加头的时候是可以的利用ButterKnife是找不到头里面的id的

RecycleView是不自带addheaderView和addFooterView的 这里的实现是想添加一item的原理 实现的

为什么找不到呢 ? 找不到就用不了ButterKnife 用不了不就不能平滑过度我原有的代码了。 虽然感觉到可能平滑过度不了了。不过还是不死心呀。然后我就看了下RecycleView和ListView的源码

RecycleView

java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.support.v7.widget.RecyclerView

ListvView

java.lang.Object
↳ android.view.View
↳ android.view.ViewGroup
↳ android.widget.AdapterView
↳ android.widget.AbsListView
↳ android.widget.ListView

从上面的结论得出 丫的俩玩意血缘上没啥关系

RecycleView没有addHeaderView方法那就看看ListView的是怎么实现的

    public void addHeaderView(View v, Object data, boolean isSelectable) {    final FixedViewInfo info = new FixedViewInfo();    info.view = v;    info.data = data;    info.isSelectable = isSelectable;    mHeaderViewInfos.add(info);    mAreAllItemsSelectable &= isSelectable;    // Wrap the adapter if it wasn't already wrapped.    if (mAdapter != null) {        if (!(mAdapter instanceof HeaderViewListAdapter)) {            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);        }        // In the case of re-adding a header view, or adding one later on,        // we need to notify the observer.        if (mDataSetObserver != null) {            mDataSetObserver.onChanged();        }    }}

上面的 mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter); 这一句很明显 是重新构建了一个adapter 替换原有的adapter

Ps:RecycleView与ListView都是利用adapter进行绘制的 为啥ListView在设置完Adapter后可以find到item里面viiew的id呢?

看源码吧
ListView源码里居然没有onDraw实现方式 AbsListView也没有 那就看onLayout吧
/**
* Subclasses should NOT override this method but
* {@link #layoutChildren()} instead.
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);

    mInLayout = true;    final int childCount = getChildCount();    if (changed) {        for (int i = 0; i < childCount; i++) {            getChildAt(i).forceLayout();        }        mRecycler.markChildrenDirty();    }    layoutChildren();    mInLayout = false;    mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;    // TODO: Move somewhere sane. This doesn't belong in onLayout().    if (mFastScroll != null) {        mFastScroll.onItemCountChanged(getChildCount(), mItemCount);    }}

又调回了子类的layoutChild 然后的就不说了 随便找个将listView源码的博客就能知道 listView 不负责自布局的绘制 而是在布局的时候就将子布局加进去了 说白了在setContentView的时候 会调用布局layout 这个时候item就已经进去的 所以findview肯定能发现id的

然而RecycleView是有onDraw的
@Override
public void onDraw(Canvas c) {
super.onDraw(c);

    final int count = mItemDecorations.size();    for (int i = 0; i < count; i++) {        mItemDecorations.get(i).onDraw(c, this, mState);    }}

它解耦的好 所以他是利用mItemDecorations这玩意绘制的,回想起来用法貌似LayoutManager才是定位的东东哦 所以RecycleView 充分解耦 他是绘制上去的而不是布局上去的

这时候问题就来了 我在使用listView+ButterKnife的时候是可以直接find到headerView里面的Id find的是第一个 正好是加头里面的 id
但是RecyckeView+ButterKnife 就find不到id 无论是第几个

因为Recycle是绘上去的!!!

上述的纯属个人理解,如有不对的地方还请指正。我还及时改正以防误人子弟及改正自己的认知错误

0 0
原创粉丝点击