• Stars
    star
    384
  • Rank 109,137 (Top 3 %)
  • Language
    Dart
  • License
    MIT License
  • Created over 3 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Flutter Flows made easy! A Flutter package which simplifies navigation flows with a flexible, declarative API.

Flow Builder

Flutter Flows made easy!

build coverage pub package

Usage

Define a Flow State

The flow state will be the state which drives the flow. Each time this state changes, a new navigation stack will be generated based on the new flow state.

class Profile {
  const Profile({this.name, this.age, this.weight});

  final String? name;
  final int? age;
  final int? weight;

  Profile copyWith({String? name, int? age, int? weight}) {
    return Profile(
      name: name ?? this.name,
      age: age ?? this.age,
      weight: weight ?? this.weight,
    );
  }
}

Create a FlowBuilder

FlowBuilder is a widget which builds a navigation stack in response to changes in the flow state. onGeneratePages will be invoked for each state change and must return the new navigation stack as a list of pages.

FlowBuilder<Profile>(
  state: const Profile(),
  onGeneratePages: (profile, pages) {
    return [
      MaterialPage(child: NameForm()),
      if (profile.name != null) MaterialPage(child: AgeForm()),
    ];
  },
);

Update the Flow State

The state of the flow can be updated via context.flow<T>().update.

class NameForm extends StatefulWidget {
  @override
  _NameFormState createState() => _NameFormState();
}

class _NameFormState extends State<NameForm> {
  var _name = '';

  void _continuePressed() {
    context.flow<Profile>().update((profile) => profile.copyWith(name: _name));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Name')),
      body: Center(
        child: Column(
          children: <Widget>[
            TextField(
              onChanged: (value) => setState(() => _name = value),
              decoration: InputDecoration(
                labelText: 'Name',
                hintText: 'John Doe',
              ),
            ),
            RaisedButton(
              child: const Text('Continue'),
              onPressed: _name.isNotEmpty ? _continuePressed : null,
            )
          ],
        ),
      ),
    );
  }
}

Complete the Flow

The flow can be completed via context.flow<T>().complete.

class AgeForm extends StatefulWidget {
  @override
  _AgeFormState createState() => _AgeFormState();
}

class _AgeFormState extends State<AgeForm> {
  int? _age;

  void _continuePressed() {
    context
        .flow<Profile>()
        .complete((profile) => profile.copyWith(age: _age));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Age')),
      body: Center(
        child: Column(
          children: <Widget>[
            TextField(
              onChanged: (value) => setState(() => _age = int.parse(value)),
              decoration: InputDecoration(
                labelText: 'Age',
                hintText: '42',
              ),
              keyboardType: TextInputType.number,
            ),
            RaisedButton(
              child: const Text('Continue'),
              onPressed: _age != null ? _continuePressed : null,
            )
          ],
        ),
      ),
    );
  }
}

FlowController

A FlowBuilder can also be created with a custom FlowController in cases where the flow can be manipulated outside of the sub-tree.

class MyFlow extends StatefulWidget {
  @override
  State<MyFlow> createState() => _MyFlowState();
}

class _MyFlowState extends State<MyFlow> {
  late FlowController<Profile> _controller;

  @override
  void initState() {
    super.initState();
    _controller = FlowController(const Profile());
  }

  @override
  Widget build(BuildContext context) {
    return FlowBuilder(
      controller: _controller,
      onGeneratePages: ...,
    );
  }

  @override dispose() {
    _controller.dispose();
    super.dispose();
  }
}

More Repositories

1

bloc

A predictable state management library that helps implement the BLoC design pattern
Dart
11,506
star
2

mason

Tools which allow developers to create and consume reusable templates called bricks.
Dart
920
star
3

equatable

A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
Dart
784
star
4

mocktail

A mock library for Dart inspired by mockito
Dart
586
star
5

cubit

Cubit is a lightweight state management solution. It is a subset of the bloc package that does not rely on events and instead uses methods to emit new states.
Dart
583
star
6

fresh

πŸ‹ A token refresh library for Dart.
Dart
271
star
7

hydrated_bloc

An extension to the bloc state management library which automatically persists and restores bloc states.
Dart
189
star
8

bloc.js

A predictable state management library that helps implement the BLoC design pattern in JavaScript
TypeScript
182
star
9

fluttersaurus

A Flutter Thesaurus made for Byteconf Flutter 2020
Dart
148
star
10

web_socket_client

A simple WebSocket client for Dart which includes automatic reconnection logic.
Dart
79
star
11

sealed_flutter_bloc

flutter_bloc state management extension that integrates sealed_unions.
Dart
70
star
12

flutter_hub

one-stop-shop to discover flutter projects, developers, and news
Dart
66
star
13

flutter_text_view_plugin

A simple flutter plugin that demonstrates how to use PlatformViews with Android to embed native views within the flutter widget tree.
Dart
43
star
14

felangel

31
star
15

bloc_library_basics_and_beyond

Bloc Library: Basics and Beyond - Flutter Europe Talk 2020
Dart
30
star
16

flutter_services_binding

A subset of WidgetsFlutterBinding specifically for initializing the ServicesBinding.
C++
27
star
17

inherited_stream

An inherited widget for Streams, which updates its dependencies when the stream emits data.
C++
22
star
18

cubit_and_beyond

Cubit and Beyond - Talk given at Flutter Vikings 2020
Dart
21
star
19

flutter_flows

A sample Flutter project which demonstrates how to use flow_builder. Part of talk given at Flutter Hub 2021
Dart
20
star
20

sealed_flutter_bloc_samples

Dart
20
star
21

rainbow_container

🌈 A magical container which changes colors whenever its build method is called.
C++
20
star
22

stream_listener

Stream Helpers for Flutter & Dart
Dart
20
star
23

meet_mason

Meet Mason: Introduction to Templating and Code Generation presented at Flutter Vikings 2022
18
star
24

cool_counter

A cool counter application which showcases HydratedCubit and ReplayCubit -- Flutter Warsaw 2020
Dart
16
star
25

broadcast_bloc

An extension to the bloc state management library which adds support for broadcasting state changes to stream channels.
Dart
16
star
26

hydrated_weather

An example of how to use hydrated_bloc to cache application state in a Weather App
Dart
15
star
27

struct

Experimental support for data classes in Dart using macros.
Dart
14
star
28

homebrew-mason

The official mason tap for homebrew
Ruby
13
star
29

codemagic_bloc_unit_tests

Bloc Unit Tests + Codemagic YAML
Dart
13
star
30

Flutter-Localization

Dart
9
star
31

simple_weather

A simple weather app built with flutter and the metaweather api.
Dart
7
star
32

bloc_todos

Dart
6
star
33

Flutter-Nested-TabBar

Dart
5
star
34

nested

A Flutter Widget which helps nest multiple widgets without needing to manually nest them.
Dart
4
star
35

flutter_platform_view_error

Ruby
3
star
36

flutter_skt_map_bug

Java
2
star
37

FelixAngelov

2
star
38

flutter_flavors_bug

C++
1
star
39

dartdevc_exception_bug

Dart
1
star
40

e2e_zones

C++
1
star
41

monorepo-ci-test

Dart
1
star
42

locale-manager

Locale-Manager is designed to be the simplest way possible to localize content while keeping an organized, scalable project structure.
JavaScript
1
star