Antecedents feed
We all know that RecyclerView is a 4-tier cache, but what exactly is 4-tier cache?
What exactly are caching and reuse?
To put it simply, caching is to store the loaded objects in the collection (List, Map) and fetch them in the collection the next time they are needed. For example: RecyclerView will slide up, slide out of the screen itemView, save to a list. And then when I load it, I’m going to fetch it directly from the List without re-creating it, which is: recycle = store the itemView into the List. RecyclerView is a ViewHolder, which is a wrapper around an itemView, and then RecyclerView is a ViewHolder, which is a wrapper around an itemView.
So what is level 4 caching
Level 4 cache is RecyclerView according to itemView different state, function, demand, etc., make four kinds of collections (to be exact, 5 collections).
Point!!
These are all arrayLists that hold ViewHolder
MViewCacheExtension is usually used for customizations, so I won’t explore it
RecycledViewPool
DEFAULT_MAX_SCRAP = 5 which is equal toArrayList<ViewHolder>
The biggest size = 5
This means that the cache pool can hold up to five Viewholders, and when more viewholders are discarded.
That is a line number > 5, sliding up and down, will always trigger the Adapter. OnCreateViewHolder, because not enough cache.
Source code analysis
reuse
Reuse is taking a ViewHolder out of a collection
- Entry: sliding Move event – > scrollByInternal – > scrollStep – > mLayout. ScrollVerticallyBy
- –> scrollBy –> fill –> layoutChunk –> layoutState.next –> addView(view);
- Entry in the finger swipe – onTouchEvent’s Move event
- scrollByInternal
- ScrollStep directly look at vertical scrolling
- Go to LinearLayoutManager. Java scrollVerticallyBy
- scrollBy
- Fill (translation)
- LayoutChunk gets the View (the itemView from the ViewHolder cached) and then adds the View to RecyclerView
- layoutState.next –> getViewForPosition –> tryGetViewHolderForPositionByDeadline
- Layoutstate. next fetches the View based on mCurrentPosition
- getViewForPosition
- TryGetViewHolderForPositionByDeadline, key!!!!!! Translation (Try to get ViewHolder according to Position within the validity period)
The focus of tryGetViewHolderForPositionByDeadline – point – level 4 slow access
This is the method that pulls the ViewHolder from the cache
He gets the ViewHolder in several ways
1. GetChangedScrapViewForPosition – mChangeScrap animation related 2. GetScrapOrHiddenOrCachedHolderForPosition – mAttachedScrap And mCachedViews 3. GetScrapOrCachedViewForId – mAttachedScrap, mCachedViews (ViewType, itemid) 4. MViewCacheExtension. GetViewForPositionAndType – custom caching 5. GetRecycledViewPool () getRecycledView – from the buffer pool to get inside
- GetChangedScrapViewForPosition get ChangedScrapView by Position
From the List of mChangeScrap, generally related to animation – level 1 cache
The List is iterated through by position or ID, which is a for loop, and then the holder is checked by if, and the holder is returned if the condition is met
- If you don’t get to, if (holder = = null), then getScrapOrHiddenOrCachedHolderForPosition (get Scrap/Hidden/Cached holder – For – the Position)
MAttachedScrap, mCachedViews from these two lists,
MAttachedScrap = Level 1 Cache, mCachedViews= Level 2 Cache
- If still didn’t get to, getScrapOrCachedViewForId, similar to the second step, only the second step in the Position to take, this in the id of the take
MAttachedScrap, mCachedViews (ViewType, itemid)
MAttachedScrap = Level 1 Cache, mCachedViews= Level 2 Cache
- Didn’t get to
mViewCacheExtension.getViewForPositionAndType
In the custom cache, generally not used
MViewCacheExtension Level 3 cache
- It’s not in RecycledViewPool yet
RecycledViewPool is a level 4 cache
- Level 4 cache didn’t get to, mAdapter. CreateViewHolder, then call mAdapter createViewHolder to create
- After created the ViewHolder has to binding, tryBindViewHolderByDeadline
Finally, it calls onBindViewHolder in the Adapter it wrote
The purpose of multi-level caching is: Performance, of course
recycling
Recycling is storing the ViewHolder into the List as the ItemView is drawn out of the screen.
- LinearLayoutManager.onLayoutChildren –> detachAndScrapAttachedViews –> scrapOrRecycleView
- LinearLayoutManager.onLayoutChildren
So onLayoutChildren is basically the same method as onLayout, but onLayout requires a lot of code, but onLayoutChildren is a simplification of onLayout.
OnLayout will be called onLayoutChildren. If you define a custom LayoutManager, rewriting onLayoutChildren will save a lot of onLayout code.
RecyclerView. Note the onLayoutChildren, if you want to custom LayoutManager that must implement this method, but a little pit, Google should be defined as the abstract, no missing
The onLayoutChildren method starts with onLayout()
- RecyclerView.detachAndScrapAttachedViews
- scrapOrRecycleView
- The main process of itemView recycling is scrapOrRecycleView
scrapOrRecycleView
Which cache to choose, scrap or RecycleView
If (viewHolder isInvalid ()) if the viewHolder is removed from the screen then go – > recycler. RecycleViewHolderInternal (viewHolder); (Internal)
else -> recycler.scrapView(view);
Specific process: – > 1). Recycler. RecycleViewHolderInternal (viewHolder); Handle CacheView, RecyclerViewPool caches
-
–> 1.ViewHodler can’t be recycled –> mCachedViews. Size is greater than the default size — recycleCachedViewAt > addViewHolderToRecycledViewPool – from the inside of the buffer pool data mCachedViews inside out
-
–> 2.addViewHolderToRecycledViewPool –> getRecycledViewPool().putRecycledView(holder); –> scrap.resetInternal(); ViewHolder empty
— — > 2). The recycler. ScrapView (view);
Recycler. RecycleViewHolderInternal (viewHolder) – processing CacheView, RecyclerViewPool cache (scrapOrRecycleView method in the if branch)
- Check whether the size of mCachedViews can be recycleCachedViewAt () or not
- The holder is added to the mCachedViews list regardless of whether the mCachedViews size exceeds the maximum
- See if the recycleCachedViewAt method exceeds the maximum mViewCacheMax
Notice that the input parameter is 0
ViewHolder ViewHolder = mCachedViews. Get (cachedViewIndex);
2. Remove the viewHolder, into the addViewHolderToRecycledViewPool (viewHolder, true); Add ViewHolder to the cache pool
3. Will mCachedViews. Remove (cachedViewIndex)
Conclusion:
- addViewHolderToRecycledViewPool
- putRecycledView
So the ViewHolder in the RecycledViewPool is empty, but the ViewHolder in the mCachedViews list is a ViewHolder with data
Recycler. ScrapView (Else branch) scrapOrRecycleView
If you don’t draw the screen cache
Add (Holder) to the mAttachedScrap or mChangedScrap list
conclusion
Copy the card
Effect:
Implement custom LayoutManager
Let’s implement one
There’s nothing to be said for that.
The focus is on customizing the LayoutManager, which used to be the LinearLayoutManager of the system
- Inheritance RecyclerView LayoutManager
Custom layoutManagers are all inherited from this
- After you inherit, you discover that you have a method to implement
Set the default LayoutParams
See what the LinearLayoutManager does
I’ll just copy it, and I’ll do it myself
- OnLayout has to be implemented, and it says that in order to customize LayoutManager you have to implement onLayoutChildren, which is in the log that Google wrote, but he didn’t abstract it
- OnLayoutChildren is mainly implemented in the layout onLayout, and reference LinearLayoutManager he also achieved RecyclerView level 4 cache recycling, reuse are realized.
Recycling: look at the source code analysis steps, recycling is detachAndScrapAttachedViews in the call
The LinearLayoutManager is also called fill ()
Fill all the way down (see above source code analysis)
–> fill –> layoutChunk –> layoutState.next –> addView(view);
LayoutState. Next. So that’s how you get out of LinearLayoutManager and into RecyclerView. Is a while loop and then traverse. Next take out each View, through the final View View = recycler. GetViewForPosition (mCurrentPosition);
So when we write our own custom LayoutManager onLayoutChildren, recycling will imitate the LinearLayoutManager
Recycling = detachAndScrapAttachedViews
I’m going to reuse =for and then I’m going to get the View through position, and then addView,
View the View = recycler. GetViewForPosition (mCurrentPosition) this
- Recycle finished writing
Counting the card that was crossed off, you only need to lay out four cards
Three decreasing cards + the last one = the bottom one.
Layout the card at the bottom first and then up the list (layout 0,1,2,3)
- onlayout
- Now that the layout is done, the items are stacked together in the middle of the screen, and you need to make it smaller, so you have to move the card down and make it smaller
Now the effect is static
Custom ItemTouchHelper
You need to be able to swipe up, down, left, and right, and you need to customize ItemTouchHelper
ItemTouchHelper is one for sliding and one for dragging. Now I just slide
- extends ItemTouchHelper.SimpleCallback
In the drag and drop method, do nothing. In the slide method, delete the DataBean and then refresh the list after adding it.
- Set the rebound time -getAnimationDuration
- Implement ontouch
OnChildDraw in this method takes the value of the slide (x,y), so we can use Pythagorean theorem to get the slide distance. You can get the percentage that slides, and then you can use that percentage to get the bottom card to zoom in on the top.
If the slider is less than one value, let it fail, otherwise it will cross out.