After a month of final exams and short semester courses, I finally had time to write the third essay. A man cannot be a eunuch. Without further ado, cut to the chase.
Hand-written Waterfall Flow with Flutter
Hand-written Waterfall Flow with Flutter
Three steps
Rewrite performLayout
This part is to set the layout information of each element, divided into three steps.
1. Initially, the layout information of the element is set.
The other functional logic must be performed first, ensuring that the element fills the entire line. This part is in the source code (276-361,myrender. Dart), this implementation is also very simple, to Element child elements, full on the next step, fill the dissatisfied into the output layout information, return.
2. The window moves up, and the layout information of the element is set.
Windows move up, that is, the finger down from the process.
You can’t just go to the shortest card at the top, and then get its index-1 and then lay it out, because that would be out of order, so you can just grab some scratch paper and draw.
How? Refer to other people’s ideas, there are probably two kinds of summary, paging (no thought) or record the subscript, here I choose the latter, that is, to record the layout of the elements correspond to which column, then the layout is directly taken. It’s called layoutChildren in the source code (254 lines).
As you move through the window, you have to find the shortest elements at the top of the already laid out elements and get their top coordinates for the layout of the new elements. Here I create a List(called leadingChildContainer in the source code) with the same length as the number of elements on the vertical axis to hold the top elements.
When you need to lay it out, you go through the table, you get, you find the shortest element at the top, you get the new element, you lay it out, and you update the table at the same time. Here’s a GIF to show you. Let’s assume that the List stores indices {[1,4],[2,5],[3,6]}, and currently only layouts up to 4,5, and 6. Update the leadingChildContainer(RenderBox) to [4,5,3] when the window moves up. Find the shortest Element 6, look up the table and find an Element 3, so find the Element with the subscript 3 and update leadingChildContainer(RenderBox) to [4,5,3].
Layout stops when the container’s layoutOffset + paintExtentOf < scrollOffset. Source code (195 lines)
3. The window is moved down, and the layout information of the element is set.
Window down, that is, the finger from the bottom up the process.
At this point, we need to find the shortest element at the bottom of the already laid out elements and get its bottom coordinates for the new element layout. Again, HERE I create a List(called trailingChildContainer in the source code) with the same length as the number of elements on the vertical axis to hold the bottom elements.
When you need to lay out, you just need to walk through the table, find the shortest element at the bottom, lay out the new element, and update the table again. So you don’t have to go through all the elements on one side to find the shortest element at the bottom, so it’s a little optimization.
I showed you that in the last GIF. So instead of 1,2,3, the List goes to 4,2,3.
The layout stops when the layoutOffset(the offset relative to the starting position) of the shortest element in the List is greater than the targetEndScrollOffset. This part of the logic is in (387-416).
4. Reclaim all elements beyond the cache scope
The logic here is simple, with two steps: reclaim the top element and reclaim the bottom element. The implementation is also simple. Remember to update both containers when using the removeChild provided by Element. (source 144,164)
Change the paint method slightly
Just change crossAxisDelta to the parentData attribute, which controls the position of the drawing, the offset from the left side of the screen.
final double crossAxisDelta =
(child.parentData as FlowSliverParentData).crossAxisPosition;
Copy the code
3. Change the official SliverMultiBoxAdaptorElement quietly
The official createChild method for creating new elements is required to ensure that the elements are incrementally incremental. Since the new elements generated when the window is moved up are not necessarily continuous (but certainly incremental), I rewrite the file here and change it to the above class in Silver.dart. The code is not stuck here and is placed in the source code render.
conclusion
Only for learning, because it is a modification of the official source code, write 💩 mountain (at least better than the previous nothing), can deal with part of the layout picture situation source code here. As for the window part of the source code has not been knocked, if you really want to achieve a clearer idea, or from the Element and widgets slowly build building blocks, about sliding, this is just the tip of the iceberg, the last final effect, to the end of the flower.