1.ListView的复用机制
2.ViewHolder的概念
1.ListView的复用机制
ListView是我们经常使用的一个控件,虽然说都会用,但是却并不一定完全清楚ListView的复用机制,虽然在Android 5.0版本之后提供了RecycleView去替代ListView和GridView,提供了一种插拔式的体验,也就是所谓的模块化。本篇主要针对ListView的复用机制进行探讨,因此就 提RecycleView。昨天看了一下郭霖大神的ListView原理深度解析的一篇博客,因此学习了一段时间,自己也说一下自己的理解。
i.RecycleBin的基本原理
首先需要说一下RecycleBin的基本原理,这个类也是实现复用的关键类。接着我们需要明确ActiveView的概念,ActivityView其实就是在UI屏幕上可见的视图(onScreenView),也是与用户进行交互的View,那么这些View会通过RecycleBin直接存储到mActivityView数组当中,以便为了直接复用,那么当我们滑动ListView的时候,有些View被滑动到屏幕之外(offScreen) View,那么这些View就成为了ScrapView,也就是废弃的View,已经无法与用户进行交互了,这样在UI视图改变的时候就没有绘制这些无用视图的必要了。他将会被RecycleBin存储到mScrapView数组当中,但是没有被销毁掉,目的是为了二次复用,也就是间接复用。当新的View需要显示的时候,先判断mActivityView中是否存在,如果存在那么我们就可以从mActivityView数组当中直接取出复用,也就是直接复用,否则的话从mScrapView数组当中进行判断,如果存在,那么二次复用当前的视图,如果不存在,那么就需要inflate View了。
这是一个总体的流程图,复用机制就是这样的。那么我们先来理解一下ListView第一次加载的时候都做了哪些工作,首先会执行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; if (changed) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { getChildAt(i).forceLayout(); } mRecycler.markChildrenDirty(); } layoutChildren(); mInLayout = false; }
这里可以看到onLayout方法会调用layoutChildren()方法,也就是对item进行布局的流程,layoutChildren()方法就不进行粘贴了,代码量过长我们只需要知道,这是对ListView中的子View进行布局的一个方式就可以了,在我们第一次加载ListView的时候,RecycleBin中的数组都没有任何的数据,因此第一次加载都需要inflate View,也就是创建新的View。并且第一次加载的时候是自顶向下对数据进行加载的,因此在layoutChildren()会执行fillFromTop()方法。fillFromTop()会执行filleDown()方法。