Flutter provide a wide range of widgets to customize your layout, most of which can be found here. However if you are like me and you don’t want to miss anything related to flutter you probably have seen a few interesting widget names. In this article I will be talking about one of these widgets,the
What the Flow Widget is NOT?
This is just a quick note before we get started if you have a Java background you may have heard of the flow layout which usually arranges components in an LRT/RTL flow, much like lines of text in a paragraph. In flutter, this is done using the Wrap widget leaving
flow to serve a different purpose when it comes to layout in Flutter.
Simple Flow Example
Let’s first start with the simplest example of the Flow widget. Once we have a basic understanding, we will look at it in greater detail and play a little more with it:
buildItem method return a simple circle with the number passed as an argument
SampleFlowDelegate is where all the fun happens
Run this piece of code and you will see just one item on the screen. This on-screen item is actually the last item. At this point, you might be thinking that the
Flow widget operates similar to
Stack. In someways, yes, they do have a few similar aspects such as the order in which the widgets are drawn. This is the reason we are only able to see the last item in our example.
So Why the Flow Layout
One good reason for using flow is it is optimized for transformation matrices, allowing you to do many kinds of crazy transformation without fear of losing performance. This is the key difference from the
Stack widget. Unlike
Stack which does all positioning and sizing during the layout phase, with
Flow,we can avoid the build phase (I will talk about that later).
This is a simple example I made while I was experimenting with this widget
Let’s try to make this layout where you can stack children on top of each other and when you double click on one of them it will expand:
Step 1: Stack children gradually
To achieve this, we need to get the size of the current child. We can easily do this using
context.getChildSize(i). Now, we multiply the height by 0.1 to get that nice effect. You can change the value to 0.5 or 0.9 to see how they layout will look.
Step 2: Animate the children
And here the power of the Flow layout shines because of the
FlowDelegate accepts an optional
repaint arguments of type
Listenable. This listenable will reprint the
Flow whenever the listeners are notified.
Step 3: Create the animation
There is nothing special here and I will link the full source code at the end of this article so you will see all the boilerplate:
Step 4: Animate on Tap / DoubleTap
Just wrap the item in
buildItem method with a
GestureDetector and set
onDoubleTap like this
And the final step is to pass the animation to the delegate
delegate: SampleFlowDelegate(openAnimation: openAnimation)
As some of you might know, we only have 16 ms to draw each frame. If we take longer than 16 ms, our app will being to drop frames, causing the UI to stutter resulting in a poor user experience. For modern devices, this is not a problem however for lower end devices try to render complex animations might be difficult. Since flow delegate repaint when the animation ticks,we save a few milliseconds.
Below is a comparison is using the previous example:
1) SetState to build when the animation ticks
2) Repaint when the animation ticks
And as you can see we eliminated the build phase completely here
So to wrap up,
Flow doesn't give you anything that you can’t get with “normal” widgets however, when it comes to animations and re-positioning widgets using translations, it does provide optimal performance.
If you’d like to give it a try check out this simple code from the example show in earlier.