Flutter has become a go-to framework for many developers due to its ease of use and flexibility. One of the packages that make Flutter stand out is the flow_builder package. This package helps manage the navigation stack and maintain the flow state in a Flutter application.
Flow Builder is a Flutter package with a declarative API for managing the navigation stack and flow state. It simplifies implementing complex navigation flows by providing a simple yet powerful API.
The flow_builder package is not limited to just navigation. It also allows developers to manage the flow state of their applications. This is crucial in scenarios such as onboarding flows where the state of the flow needs to be maintained across various screens.
To use Flowbuilder, you need to add it as a dependency in your pubspec.yaml file.
1dependencies: 2 flow_builder: ^latest_version 3
The flow state is the one that controls the flow. Each time this state changes, a new navigation stack is created depending on the new flow state.
1class Profile { 2 const Profile({this.name, this.age, this.weight}); 3 4 final String? name; 5 final int? age; 6 final int? weight; 7 8 Profile copyWith({String? name, int? age, int? weight}) { 9 return Profile( 10 name: name ?? this.name, 11 age: age ?? this.age, 12 weight: weight ?? this.weight, 13 ); 14 } 15} 16
The FlowBuilder widget creates a navigation stack in response to changes in the flow state. OnGeneratePages will be called for each state change, and it must return the new navigation stack as a list of pages.
1FlowBuilder<Profile>( 2 state: const Profile(), 3 onGeneratePages: (profile, pages) { 4 return [ 5 MaterialPage(child: NameForm()), 6 if (profile.name != null) MaterialPage(child: AgeForm()), 7 ]; 8 }, 9); 10
The state of the flow can be updated via context.flow<T>().update
.
1class NameForm extends StatefulWidget { 2 3 _NameFormState createState() => _NameFormState(); 4} 5 6class _NameFormState extends State<NameForm> { 7 var _name = ''; 8 9 void _continuePressed() { 10 context.flow<Profile>().update((profile) => profile.copyWith(name: _name)); 11 } 12 13 14 Widget build(BuildContext context) { 15 return Scaffold( 16 appBar: AppBar(title: const Text('Name')), 17 body: Center( 18 child: Column( 19 children: <Widget>[ 20 TextField( 21 onChanged: (value) => setState(() => _name = value), 22 decoration: InputDecoration( 23 labelText: 'Name', 24 hintText: 'John Doe', 25 ), 26 ), 27 RaisedButton( 28 child: const Text('Continue'), 29 onPressed: _name.isNotEmpty ? _continuePressed : null, 30 ) 31 ], 32 ), 33 ), 34 ); 35 } 36} 37
The flow can be completed via context.flow<T>().complete
.
1class AgeForm extends StatefulWidget { 2 3 _AgeFormState createState() => _AgeFormState(); 4} 5 6class _AgeFormState extends State<AgeForm> { 7 int? _age; 8 9 void _continuePressed() { 10 context 11 .flow<Profile>() 12 .complete((profile) => profile.copyWith(age: _age)); 13 } 14 15 16 Widget build(BuildContext context) { 17 return Scaffold( 18 appBar: AppBar(title: const Text('Age')), 19 body: Center( 20 child: Column( 21 children: <Widget>[ 22 TextField( 23 onChanged: (value) => setState(() => _age = int.parse(value)), 24 decoration: InputDecoration( 25 labelText: 'Age', 26 hintText: '42', 27 ), 28 keyboardType: TextInputType.number, 29 ), 30 RaisedButton( 31 child: const Text('Continue'), 32 onPressed: _age != null ? _continuePressed : null, 33 ) 34 ], 35 ), 36 ), 37 ); 38 } 39} 40
A FlowBuilder can also be created with a custom FlowController in cases where the flow can be manipulated outside of the sub-tree.
1class MyFlow extends StatefulWidget { 2 3 State<MyFlow> createState() => _MyFlowState(); 4} 5 6class _MyFlowState extends State<MyFlow> { 7 late FlowController<Profile> _controller; 8 9 10 void initState() { 11 super.initState(); 12 _controller = FlowController(const Profile()); 13 } 14 15 16 Widget build(BuildContext context) { 17 return FlowBuilder( 18 controller: _controller, 19 onGeneratePages: ..., 20 ); 21 } 22 23 dispose() { 24 _controller.dispose(); 25 super.dispose(); 26 } 27} 28
A FlowController is created and used to control the flow in the above snippet. The FlowController is disposed of in the dispose method to free up resources when the widget is removed from the widget tree.
Flow Builder is a powerful and flexible package for Flutter. It simplifies the navigation and state management in Flutter applications. With Flow Builder, you can easily create complex navigation flows and maintain the state of these flows. Whether you are developing for Android, iOS, or any other platform that Flutter supports, Flow Builder is a package you should consider using in your Flutter applications. It not only simplifies the process of creating and managing navigation flows but also provides a clean and maintainable way to handle state changes in your application.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.