See this section of the previous Flutter simple implementation hand-written waterfall flow Widget. The cover is a quick sliding frame map after loading the picture.
The realization of the RenderObject
The previous Widget has a createRenderObject method that creates information about the layout and draws it. By looking at RenderSliverList source, found that its layout is through inheritance RenderSliverMultiBoxAdaptor class implements, and rewrite the performLayout method. This method sets where each element should be placed.
By looking at the source code, we know that this class is abstract and has three mixins.
Key members and methods are as follows
// Is essentially an Element that manages a large number of cards in the layout
final RenderSliverBoxChildManager _childManager;
// Set the layout information for each card, such as the offset relative to the starting point of the slide
void setupParentData(RenderObject child);
// Initialize the layout usage, more on that later
bool addInitialChild({ int index = 0.double layoutOffset = 0.0});// Give the subscript of RenderBox, which is the number of cards
int indexOf(RenderBox child);
// Return the drawing height of the card
double paintExtentOf(RenderBox child) ;
// Return the offset of the given card relative to the starting point of the slide
double? childScrollOffset(RenderObject child);
// call to draw output to the screen
void paint(PaintingContext context, Offset offset);
Copy the code
Pit tips (you can skip them first)
1. In the layout method parameter of the RenderBox, the parentUsesSize property must be set to true, otherwise the parent element cannot access its size information.
2. When using childManager.creatChild to create a new card or to remove an old card using childManager.removechild, Make sure to write this inside the invokeLayoutCallback((SliverConstraints){}) to tell the RenderObject to change the RenderTree, otherwise it will get a red error page. The reason for this call is written in the RenderObject source code.
The implementation process
The realization of the gridDelegate
First of all, we must have a is used to set the vice shaft should be placed on a few class card, here I copy the corresponding SliverGridDelegateWithFixedCrossAxisCount SliverGrid implementation.
class FlowSliverDelegateWithFixedCrossAxisCount extends FlowSliverDelegate {
const FlowSliverDelegateWithFixedCrossAxisCount({
required this.crossItemCount,
});
final int crossItemCount; // Set the number of cards on the secondary axis
}
Copy the code
The realization of the ParentData
Then we each card should have a relative to the offset of the spindle what is recorded in the column of information, for the use of layout, inherited SliverMultiBoxAdaptorParentData here, the parent class provides the index, keepAlive variable information. ParentData is a property of RenderBox, and the parent can only access its information when the property in pit point 1 is true!
class FlowSliverParentData extends SliverMultiBoxAdaptorParentData {
// The spindle offset can be thought of as a few pixels to the left of the phone screen
double crossAxisPosition = 0.0;
}
Copy the code
Overwrite the paint method
Paint is the last thing called at runtime, but I put it there because it’s not much. Here are some of the important constants in this method, and the rest will follow suit. Note that the actual drawing is done with the screen as the coordinate system, with the top left corner at zero. The following parameters describe the drawing object on the axis information!
// The child here is RenderBox
// How many pixels from the top of the screen should be drawn
final double mainAxisDelta = childMainAxisPosition(child);
// How many pixels from the left side of the screen should be drawn
final double crossAxisDelta = (child.parentData as FlowSliverParentData).crossAxisPosition;
// Ok, I'll start drawing
context.paintChild(child, childOffset);
Copy the code
Rewrite performLayout.
The core part, the most troublesome part
This method sets the parentData parameters of the RenderBox for each card, mainly setting the parentData layoutOffset(offset relative to the starting point of the slide),crossAxisPosition(offset relative to the left side of the screen), Make it have the correct location information in the later paint() method.
Here, we have to do three things.
1. Set the layout using constraints given by the parent element (viewPort). (Check out the basics link for the first article.)
2. Call layout() for the RenderBox that appears in the window range, and set its parentData so that it has the correct location information.
3. Output layout information to the geometry variable. The geometry of the SliverGeometry section is long.
The layout algorithm will be covered in the next article, along with the source code (fear).
Method for performLayout
1. Create and destroy elements using the Remove and create methods provided by childManager.
2. Used in reference to SliverList childManager with the output of the geometry information estimateMaxScrollOffset, calculatePaintOffset, calculateCacheOffset three methods.
The next article is here