This blog assumes that you have a beginner’s knowledge in Flutter. Otherwise, dive into to get the basics and come right back!
Now, how do we layout widgets in Flutter? Normally we use a stack, row or column. But what if our requirement is more than that? If we want to arrange some widgets horizontally, we use a Row Widget. If we want to arrange them vertically, we would wrap them in a Column and use Stack to arrange elements on top of another. But we can’t expect our UI to be so simple as that. For example, I was met with a requirement of a circular widget with five equally spaced buttons located on it (check out the image below!).
Don’t worry! We can do it with a CustomMultiChildLayout widget which takes only two arguments.
CustomMultiChildLayout(delegate: _CircularLayoutDelegate(itemCount: 5,Radius: 150.0,),children: products,)
for (int i = 0; i < 5; i++) {products.add( LayoutId(id: ‘BUTTON$i’,child: item,));}
Now, the important part is the delegate. The MultiChildLayoutDelegate is an abstract class. So, we have to extend it for our use. Override the method performLayout and we can write the code to position items in it.
class _CircularLayoutDelegate extends MultiChildLayoutDelegate {static const String actionButton = 'BUTTON';Offset center;final int itemCount;final double radius;
_CircularLayoutDelegate({@required this.itemCount,@required this.radius,});
@overridevoid performLayout(Size size) {center = Offset(size.width / 2, size.height / 2);for (int i = 0; i < itemCount; i++) {final String actionButtonId = '$actionButton$i';
if (hasChild(actionButtonId)) {
final Size buttonSize =
layoutChild(actionButtonId, BoxConstraints.loose(size));
final double itemAngle = \_calculateItemAngle(i);
positionChild(
actionButtonId,
Offset(
(center.dx - buttonSize.width / 2) + (radius) \* Math.cos(itemAngle),
(center.dy - buttonSize.height / 2) +
(radius) \* Math.sin(itemAngle),
),
);
}}}
@overridebool shouldRelayout(_CircularLayoutDelegate oldDelegate) =>itemCount != oldDelegate.itemCount ||radius != oldDelegate.radius ;}
const double _radiansPerDegree = Math.pi / 180;final double _startAngle = -90.0 * _radiansPerDegree;double _itemSpacing = 360.0 / 5.0;double _calculateItemAngle(int index) {return _startAngle + index * _itemSpacing * _radiansPerDegree;}
6. Finally, positionChild method is called with the id of the item and the offset. The offset is calculated using the mathematical equation,
A point at angle theta on the circle whose centre is (x0,y0) and whose radius is r is (x0 + r cos theta, y0 + r sin theta).
7. The shouldRelayout method is called to compare the current layout and the old one and return true if a relayout is needed.
So, that’s how easy it is to create custom layouts in Flutter. If you want to read more about our Flutter experience, check out our recent blog. Flutter has always been our core areas of expertise. So, stay tuned for more similar updates and information exchange!
You can further learn about our Flutter contributions in GitHub.
Originally published at https://www.sayonetech.com/blog/how-create-custom-layout-widgets-flutter/.