Flutter Flow widget Example
Last updated Mar 03, 2021In this post we are going to learn about flow widget and its usage. If we need to create an animation that transforms the position of the children then we can use the flow widget.
Flow is a widget which arranges its child widgets based on FlowDelegate
Constructor
Flow({
Key key,
@required this.delegate,
List<Widget> children = const <Widget>[],
})
|
To use Flow widget we need to pass FlowDelegate, which will control the appearance of the child widgets.
Create FlowDelegate
To create FlowDelegate instance
, we need to create a custom class which extends FlowDelegate
.
This FlowDelegate contains below methods:
- Constructor with super() call super(repaint: )
-
void paintChildren(FlowPaintingContext context)
-
bool shouldRepaint(FlowExampleDelegate oldDelegate)
-
BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints)
-
Size getSize(BoxConstraints constraints)
void paintChildren(FlowPaintingContext context)
FlowPaintingContext
itself has some properties and methods.
Size get size
: The size of the container in which the children can be painted.int get childCount
: The number of children available to paint.Size? getChildSize(int i)
: The size of thei
th child.void paintChild(int i, { Matrix4 transform, double opacity = 1.0 })
: Used to paint thei
th child
Size getSize(BoxConstraints constraints)
By default implementation of FlowDelegate
's getSize
method returns the biggest size that satisfies the constraints
|
We can also set the required size for the child items by
Size getSize(BoxConstraints constraints) {
return Size(70.0, double.infinity);
}
|
BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints)
By default, the children will use the given size constraints. That's because the default implementation of getConstraintsForChild
method returns the given constraints
We can set the customize contraints by
BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints) {
return i == 0 ? constraints : BoxConstraints.tight(const Size(50.0, 50.0));
}
|
Complete example of Flow widget
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'rrtutors.com Flutter Tutorial',
home: Scaffold(
appBar: AppBar(
title: const Text('Flow Widget Example'),
backgroundColor: Colors.pink,
),
body: FlowExample(),
),
);
}
}
class FlowExample extends StatefulWidget {
@override
_FlowExampleState createState() => _FlowExampleState();
}
class _FlowExampleState extends State<FlowExample>
with SingleTickerProviderStateMixin {
AnimationController _myAnimation;
final List<IconData> _icons = <IconData>[
Icons.menu,
Icons.email,
Icons.new_releases,
Icons.notifications,
Icons.bluetooth,
Icons.wifi,
];
@override
void initState() {
super.initState();
_myAnimation = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
);
}
Widget _buildItem(IconData icon) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: RawMaterialButton(
fillColor: Colors.pinkAccent,
splashColor: Colors.grey,
shape: CircleBorder(),
constraints: BoxConstraints.tight(Size.square(50.0)),
onPressed: () {
_myAnimation.status == AnimationStatus.completed
? _myAnimation.reverse()
: _myAnimation.forward();
},
child: Icon(
icon,
color: Colors.white,
size: 30.0,
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(color: Colors.grey),
Flow(
delegate: FlowExampleDelegate(myAnimation: _myAnimation),
children: _icons
.map<Widget>((IconData icon) => _buildItem(icon))
.toList(),
),
],
);
}
}
class FlowExampleDelegate extends FlowDelegate {
FlowExampleDelegate({this.myAnimation}) : super(repaint: myAnimation);
final Animation<double> myAnimation;
// Put overridden methods here
@override
bool shouldRepaint(FlowExampleDelegate oldDelegate) {
return myAnimation != oldDelegate.myAnimation;
}
@override
void paintChildren(FlowPaintingContext context) {
for (int i = context.childCount - 1; i >= 0; i--) {
double dx = (context.getChildSize(i).height + 10) * i;
context.paintChild(
i,
transform: Matrix4.translationValues(0, dx * myAnimation.value + 10, 0),
);
}
}
@override
Size getSize(BoxConstraints constraints) {
return Size(70.0, double.infinity);
}
@override
BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints) {
return i == 0 ? constraints : BoxConstraints.tight(const Size(50.0, 50.0));
}
}
|
Article Contributed By :
|
|
|
|
2450 Views |