The answer is at the end of the article
When it comes to RecyclerView, reuse is one of the things we can talk about. The built-in ViewHolder avoids the hassle of manually creating a ViewHolder when using a ListView. Can we be sure when to recycle and reuse views? When we slide a RecyclerView, do we recycle the View and reuse the View? Or do you reuse the View first and then recycle the View? The answer is both. For details, see the following analysis:
Noun explanation
1. Recycling: The View does not need to be displayed on the screen any more and is recycled to the recycling pool
2. Reuse: Reuse in this article refers to the call to the onCreateViewHolder or onBindViewHolder methods
1. Two scenarios of sliding RV
1.1 a scene
Each Item in the RV is 100px high, and the last Item is 50px off the screen. The initial state of RV is shown below
Q1 assumes an upward slide of 40px
Have views been recycled or reused? If so, reuse or recycle first?
Q2 is assumed to slide up 60px
Have views been recycled or reused? If so, reuse or recycle first?
Q3 assumes an upward swipe of 120px
Have views been recycled or reused? If so, reuse or recycle first?
1.2 scenario 2
The first Item in the RV is 50px tall, the others are 100px, and the last Item is 95px off the screen. The initial state of the RV is as follows
Q1 assumes an upward slide of 40px
Have views been recycled or reused? If so, reuse or recycle first?
Q2 is assumed to slide up 60px
Have views been recycled or reused? If so, reuse or recycle first?
Q3 assumes an upward swipe of 120px
Have views been recycled or reused? If so, reuse or recycle first?
You can see from the answer. There is no fixed answer to recycling and reuse. It varies from scene to scene. Here’s an example to verify the answer.
2. Verify the answer by DEMO
2.1 Let’s verify scenario 1
Program running diagram
The program code
The log output is as follows
Let’s go to the initial state
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 0
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 1
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 2
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 3
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 4
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 5
Click and slide up 40px. The printed logs remain unchanged. Prove that neither recycling nor reuse has occurred
Click and slide up 60px. The following logs are displayed: Prove that no recycling has occurred and that reuse has occurred
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 0
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 1
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 2
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 3
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 4
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 5
RecyclerView onCreateViewHolder // Only RecyclerView onBindViewHolder 6 occurred
Click and swipe up 120px. The following logs are displayed: Demonstrate that recycling and reuse have occurred. Reuse before recycling
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 0
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 1
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 2
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 3
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 4
RecyclerView Scenario 1 onCreateViewHolder
RecyclerView Scenario 1 onBindViewHolder 5
RecyclerView Scenario 1 onCreateViewHolder // Reuse
RecyclerView Scenario 1 onBindViewHolder 6
RecyclerView Scenario 1 Recycle item 0 // Recycle item
2.2 Let’s verify scenario 2
Program running diagram
The program code
Log output enters the initial state first
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 0
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 1
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 2
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 3
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 4
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 5
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 6
Click and slide up 40px. The printed logs remain unchanged. Prove that neither recycling nor reuse has occurred
Click and slide up 60px. The following logs are displayed: Prove that recycling has occurred and no reuse has occurred
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 0
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 1
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 2
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 3
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 4
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 5
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 6
RecyclerView Scenario 2 Recycle Item 0 // Recycle only
Click and swipe up 120px. The following logs are displayed: Demonstrate that recycling and reuse have occurred. Recycle before reuse
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 0
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 1
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 2
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 3
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 4
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 5
RecyclerView Scenario 2 onCreateViewHolder
RecyclerView Scenario 2 onBindViewHolder 6
RecyclerView Scenario 2 Recycle item 0 // Recycle item first
RecyclerView Scenario 2 onBindViewHolder 7 // Reuse
3. Sliding principle analysis
3.1 Related Parameters
As shown, introduce some parameters about coordinates
-
Delta: finger slide distance 120px.
-
MOffset: RV The Bottom of the last subview is 600px Y in the screen coordinate system. The next View(Item7) of the RV is laid out from the mOffset.
-
MScrollingOffset: RV The distance between the Bottom of the last subview and the RV Bottom is 50px. Slide up not to exceed this distance. If it does, create a new View fill.
-
MVailable: delta – mScrollingOffset. You can fill the View space. If it is greater than 0, there is room to fill the new View
-
If delta<mScrollingOffset, mScrollingOffset=delta, mVailable<0, that is, the sliding distance is less than mScrollingOffset, do not fill the new View
3.2 Slide fill and recycle logic
The sliding logic is as follows
-
RecyclerView from the 0 View start traversal, until the View Bottom>mScrollingOffset, and record the View index, recycle [0,index) interval View,index is open interval, If index>=1, the View in the range [0,index) will be removed from the screen and put into the recycling pool according to the recycling algorithm. For the specific recycling algorithm, press no table first.
-
If mVailable>0, fill it with a new View from mOffset. MOffset += New View height, mVailable-= New View height, mScrollingOffset+= New View height, if mVailable<0, mScrollingOffset+=mVailable. After the layout is complete, recycle the View as required using the algorithm of Step 1.
-
Repeat Step 2
-
Move the RV as a whole up the delta or consumed distance (generally delta distance, but the specific consumed distance when there is no Item under RecyclerView)
The code for logic 1 is as follows
Logic 2 populates the View code as follows
3.3 Analyzing Scenario 1
Based on this slide logic, we analyzed the slide up 120px in scene 1
mOffset = 600px
mScrollingOffset = 50px
mAvailable = 70px
Item1 height 100 px
-
Start by traversing Bottom>50px from the 0th View. Find Item1. bottom=100px and record index=0. Because the index < 1. So no collection takes place
-
MAvailable >0, add View Item7 height 100px, mOffset=700px, mAvailable=-30 from the bottom of Item6 MScrollingOffset = mScrollingOffset + 100-30 = 120 px. Then check for recycling. Start by traversing the Bottom>120px from the 0th View. Find Item2. bottom=200px and record index=1. Recycle View in range [0,1), i.e. recycle Item1
-
MAvailable =-30<0, exit the filling logic
-
Overall move up 120px
We saw that we created Item7 and then reclaimed Item1. It matches the log
RecyclerView onCreateViewHolder // Reuse RecyclerView onBindViewHolder 6
RecyclerView Scenario 1 Recycle item 0 // Recycle item
The same logic can be used to analyze the slide up 120px in scenario 2. In scenario 2, recycling occurs before reuse. Readers can find out for themselves.
4. Source code analysis
The RV slide ends up calling the scrollBy method of LayoutManager. We use a linear Layer outManager.
-
The updateLayoutState method is used to calculate parameters such as mOffset.
-
The fill method in code 2 fills the View according to the remaining space
-
Code 3 offsetChildren, moving the RV subview as a whole
-
In code 1, first determine whether the View needs to be reclaimed
-
In code 2, determine whether the View needs to be populated based on the remaining space
-
Listing 3 shows the specific Layout method
-
When a single layout is complete, determine whether the View needs to be recycled
5. Ask questions and interact
Finally, to reinforce your understanding, ask a question, please write your answer in the comments section.
In case3 of scenario 1, swipe up 120px and 120px is 100px higher than the height of the first Item. Why not recycle Item1 first?
Question 2: What might be the reason for Google’s design?
Follow bytecode’s public account and reply “scroll” to get answers