Reuse and caching mechanism of ListView

Posted by lightpace on Sat, 04 Jan 2020 01:14:57 +0100

Reuse analysis

**1. In the AbListView**

/**
 * The data set used to store unused views that should be reused during the next layout
 * to avoid creating new ones
 */
final RecycleBin mRecycler = new RecycleBin();

RecycleBin contains two levels of storage, ActiveViews and ScrapViews. ActiveViews stores the View displayed on the screen for the first time; all ActiveViews will be moved to ScrapViews eventually, and ScrapViews stores the View that may be reused by adapter.

**2. In LayoutChildren of ListView**

@Override
protected void layoutChildren() 
{
    if (dataChanged) 
    {
        for (int i = 0; i < childCount; i++) 
        {
            recycleBin.addScrapView(getChildAt(i));   
        }
    } else 
    {
        recycleBin.fillActiveViews(childCount, firstPosition);
    }
    ....
}

It can be seen that if the data changes, the current ItemView will be put into ScrapViews, otherwise the currently displayed ItemView will be put into ActiveViews.

3. Where is our key getView method called
In the AbsListView, let's look at the methods in the obtainView:

/**
 * Get a view and have it show the data associated with the specified
 * position. This is called when we have already discovered that the view is
 * not available for reuse in the recycle bin. The only choices left are
 * converting an old view or making a new one.
 *
 * @param position The position to display
 * @param isScrap Array of at least 1 boolean, the first entry will become true if
 *                the returned view was taken from the scrap heap, false if otherwise.
 * 
 * @return A view displaying the data associated with the specified position
 */
View obtainView(int position, boolean[] isScrap) 
{
    final View scrapView = mRecycler.getScrapView(position);
    final View child = mAdapter.getView(position, scrapView, this);
    if (scrapView != null) {
        if (child != scrapView) {
            // Failed to re-bind the data, return scrap to the heap.
            mRecycler.addScrapView(scrapView, position);
        } else {
            isScrap[0] = true;

            child.dispatchFinishTemporaryDetach();
        }
    }

    return child;
}

It can be seen that this method is to return the display of the current Item of a layout user. First, search for position based on ScrapView, then find our getView, then convertView!=null in getView, then getView will change if View is returned, otherwise it will be convertView==null.

Reference material

Link: https://www.jianshu.com/p/e31cd6703726
 

Topics: Android