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

Overview

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();
  }
}
Comments
  • Physical back button close app from nested FlowBuilder (the first is to manage pages at same level)

    Physical back button close app from nested FlowBuilder (the first is to manage pages at same level)

    Describe the bug I'm trying to manage nested flow builders starting from a Drawer. If I press physical back button from nested page (NEWS DETAILS for example) the app closes.

                     ROOT PAGE (with drawer)
                  /            |           \
                 HOME         NEWS        SETTINGS
                               |
                            DETAILS
                               |
                            ANOTHER
    

    The solution can be use IndexedStack for pages of root level, but I will want use FlowBuilder for experiment.

    To Reproduce Steps to reproduce the behavior:

    1. Open the drawer
    2. Tap on "NEWS"
    3. Tap on FAB to go on next page
    4. Press physical back button

    Expected behavior The navigator pop back to previous page.

    Flutter Doctor
    [✓] Flutter (Channel dev, 1.23.0-7.0.pre, on Mac OS X 10.15.6 19G2021 x86_64, locale it-IT)
        • Flutter version 1.23.0-7.0.pre at **/master
        • Framework revision db6e2d8aa5 (9 weeks ago), 2020-09-25 06:47:03 -0400
        • Engine revision 3a73d073c8
        • Dart version 2.11.0 (build 2.11.0-161.0.dev)
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
        • Android SDK at /**/Library/Android/sdk
        • Platform android-30, build-tools 30.0.2
        • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 11.5)
        • Xcode at /Volumes/Samsung_X5/Applications/Xcode.app/Contents/Developer
        • Xcode 11.5, Build version 11E608c
        • CocoaPods version 1.8.4
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [!] Android Studio (version 4.1)
        • Android Studio at /Applications/Android Studio.app/Contents
        ✗ Flutter plugin not installed; this adds Flutter specific functionality.
        ✗ Dart plugin not installed; this adds Dart specific functionality.
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2020.2.3)
        • IntelliJ at /Applications/IntelliJ IDEA.app
        • Flutter plugin installed
        • Dart plugin version 202.8070
    
    [✓] VS Code (version 1.51.1)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.16.0
    
    [✓] Connected device (4 available)
        • Pixel 2 XL (mobile) • 711KPWQ0617241 • android-arm64  • Android 11 (API 30)
        • macOS (desktop)     • macos          • darwin-x64     • Mac OS X 10.15.6 19G2021 x86_64
        • Web Server (web)    • web-server     • web-javascript • Flutter Tools
        • Chrome (web)        • chrome         • web-javascript • Google Chrome 87.0.4280.67
    
    ! Doctor found issues in 1 category.
    

    Additional context I have simplified the example to a minimum Here the code

    bug 
    opened by giandifra 11
  • Page does not change despite state changing

    Page does not change despite state changing

    Describe the bug The last page is frozen in page stack despite there is a new page should be.

    I use _onGeneratePages this way:

    [
    if (flowState.input != null) NameForm(),
    if (flowState.input == null && (flowState.medications?.isNotEmpty ?? false))
      SummaryPage(),
    ]
    

    Flutter version is 2.2.2

    I'm sure(I debugged and checked all things) that after state update only NameForm in the stack. But SummaryPage is still on the screen. Might it be Navigator issue...

    I'm trying downgrade now. Might someone have the same issue?

    question 
    opened by dan-leech 10
  • Cannot pop the page with Android back button when using Navigator.push<Type>

    Cannot pop the page with Android back button when using Navigator.push

    Describe the bug When using flow_builder the Android back button can break if using navigation push with return type argument.

    To Reproduce Steps to reproduce the behavior:

    1. Execute the below sample on Android device
    2. Press Navigate with <void>, then navigate back using Android back button
    3. Press Navigate with <NavigationResult?>, then navigate back using Android button
    4. In the second case the page is not popped
    5. Press back button again, the app closes
    import 'package:flow_builder/flow_builder.dart';
    import 'package:flutter/material.dart';
    
    enum NavigationResult {
      save,
      cancel,
    }
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: FlowBuilder<int>(
            state: 1,
            onGeneratePages: (state, pages) => [
              const MaterialPage(
                child: MyHomePage(),
              ),
            ],
          ),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Home'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ElevatedButton(
                  onPressed: () {
                    Navigator.of(context).push(DetailsPage.route('1'));
                  },
                  child: const Text('Navigate with <void>'),
                ),
                ElevatedButton(
                  onPressed: () {
                    Navigator.of(context)
                        .push<NavigationResult?>(DetailsPage.resultRoute('1'));
                  },
                  child: const Text('Navigate with <NavigationResult?>'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class DetailsPage extends StatelessWidget {
      const DetailsPage({Key? key}) : super(key: key);
    
      static Route<NavigationResult?> resultRoute(String id) =>
          MaterialPageRoute<NavigationResult?>(
            builder: (_) => const DetailsPage(),
            settings: const RouteSettings(name: '/test'),
          );
    
      static Route<void> route(String id) => MaterialPageRoute(
            builder: (_) => const DetailsPage(),
            settings: const RouteSettings(name: '/test'),
          );
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Details'),
            centerTitle: true,
          ),
          body: const Center(
            child: Text('Details Page'),
          ),
        );
      }
    }
    

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots

    https://user-images.githubusercontent.com/16854239/163337695-5d28d4a1-9973-435c-9eac-69b6a313c4f6.mp4

    Logs

    Running on Android 9, but this also is a problem on Android 12

    name: navigation_error
    description: A new Flutter project.
    
    publish_to: "none"
    
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.16.2 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
    
      cupertino_icons: ^1.0.2
      flow_builder: ^0.0.6
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
      flutter_lints: ^1.0.0
    
    flutter:
      uses-material-design: true
    
    [✓] Flutter (Channel stable, 2.10.4, on macOS 12.3 21E230 darwin-arm, locale pl-PL)
    [✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
    [✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
    [✓] Chrome - develop for the web
    [✓] Android Studio (version 2021.1)
    [✓] VS Code (version 1.66.1)
    [✓] Connected device (3 available)
    [✓] HTTP Host Availability
    

    Additional context Add any other context about the problem here.

    bug 
    opened by orestesgaolin 9
  • url paths?

    url paths?

    New navigator has the ability to request certain url paths....how does this work with flow builder?

    thanks for the excellent open source contributions! Regards, Hans

    enhancement 
    opened by hansbak 6
  • Prevent repeated calls of

    Prevent repeated calls of "onComplete"

    Once a flow was completed, navigating back through the flow by popping causes the onComplete handler to fire again on every pop.

    I can prevent this by manually wrapping my callback code into a check whether the current state is in fact the "last" state before actually executing its logic, but would prefer if this was built-in, e.g. by setting the private _completed property to false automatically anytime a _history state gets restored.

    Am I missing something that would make this a bad idea?

    bug 
    opened by Lootwig 5
  • [Feature Request] `FlowController<T>` should implement `ValueListenable<T>` instead of `Listenable`

    [Feature Request] `FlowController` should implement `ValueListenable` instead of `Listenable`

    Is your feature request related to a problem? Please describe. Currently flow_builder can't be used to build widgets. Although flow_builder's responsibility is building the navigation stack, users could also benefit from being able to use ValueListenableBuilder with a FlowController.

    Describe the solution you'd like FlowController<T> should implement ValueListenable<T> instead of Listenable. The only downside is this would force FlowController to override ValueListenable's value. Right now the value's role is played by the state property. Couple of options to overcome this:

    • override value with:
    @override
    T get value => _notifier.value;
    

    and leave the rest of the implementation as it is. Weird solution to say the least, but I guess it's the only way to keep the state naming 🙄

    • override value with:
    @override
    T get value => _notifier.value;
    

    and deprecate state for the next release; we could then remove state and keep value to better align with flutter naming conventions. I'd prefer this route.

    If you like this change I'm willing to open a PR.

    question 
    opened by narcodico 5
  • Multiple flow_builder in an app

    Multiple flow_builder in an app

    I just started learning how to use this (very useful) package and have a question relating to its usage: Suppose my app has multiple flows e.g. authentication flow then profile flow etc., how should I handle combining these flows together? Should I just add the profile flow on top of the authentication flow?

    Thank you!

    question 
    opened by utipe 5
  • Flutter build fails after upgrade to flow_builder-0.0.7

    Flutter build fails after upgrade to flow_builder-0.0.7

    Describe the bug Flutter build fails after upgrade to flow_builder-0.0.7 from flow_builder-0.0.6.

    To Reproduce Steps to reproduce the behavior:

    1. Upgrade to flow_builder-0.0.7 from flow_builder-0.0.6.
    2. Run app (F5)
    3. Build fails with error messages below:
    4. Fixed the problem by directly editing C:\sdk\flutter.pub-cache\hosted\pub.dartlang.org\flow_builder-0.0.7\lib\flow_builder.dart, lines 367 and 372, adding null operator [?] after WidgetsBinding.instance?

    /C:/sdk/flutter/.pub-cache/hosted/pub.dartlang.org/flow_builder-0.0.7/lib/flow_builder.dart:367:36: Error: Method 'handlePopRoute' cannot be called on 'WidgetsBinding?' because it is potentially null.

    • 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/C:/sdk/flutter/packages/flutter/lib/src/widgets/binding.dart'). package:flutter/…/widgets/binding.dart:1 Try calling using ?. instead. return WidgetsBinding.instance.handlePopRoute(); ^^^^^^^^^^^^^^ /C:/sdk/flutter/.pub-cache/hosted/pub.dartlang.org/flow_builder-0.0.7/lib/flow_builder.dart:372:38: Error: Method 'handlePushRoute' cannot be called on 'WidgetsBinding?' because it is potentially null.

    • 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/C:/sdk/flutter/packages/flutter/lib/src/widgets/binding.dart'). package:flutter/…/widgets/binding.dart:1 Try calling using ?. instead. return WidgetsBinding.instance.handlePushRoute(arguments);

    question 
    opened by GerhardMalan 4
  • Provide an example for custom FlowController

    Provide an example for custom FlowController

    Hi, I've been trying to figure out how could I control the flow via BLoC states (I've been working with flutter_bloc).

    I tried implementing FlowController and using it from my bloc but I had no luck. Moreover, controlling everything from a bloc will make me lose the "pop" event so I'm not sure of what "Since Flow Builder represents navigation as a function of state, it can be used with whatever state management solution you have chosen" means.

    Can you provide an example that shows how I can hook up the navigation accordingly to the state change of a bloc?

    Even if not controlling the flow from a bloc it would be great if FlowController could provide some sort of event to listen to in order to update the bloc accordingly to page changes!

    Thank you!

    documentation question 
    opened by magicleon94 4
  • chore: v0.0.5

    chore: v0.0.5

    Status

    READY

    Breaking Changes

    NO

    Description

    Bump version 0.0.5 to update the package in pub.dev

    Type of Change

    • [ ] ✨ New feature (non-breaking change which adds functionality)
    • [x] 🛠️ Bug fix (non-breaking change which fixes an issue)
    • [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] 🧹 Code refactor
    • [ ] ✅ Build configuration change
    • [ ] 📝 Documentation
    • [ ] 🗑️ Chore
    • [ ] 🧪 Testing
    opened by maherjaafar 3
  • Nested flows cause issues with Android's back button

    Nested flows cause issues with Android's back button

    Describe the bug Nested flows cause unintended behavior on Android.

    When two flows are nested inside each other, the back button on Android will close out the app.

    To Reproduce N/A

    Expected behavior The back button should close out of the inner flow and go back to the outer one.

    flutter doctor -v output

    [√] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.18363.1256], locale en-US)
        • Flutter version 1.22.5 at C:\flutter
        • Framework revision 7891006299 (5 weeks ago), 2020-12-10 11:54:40 -0800
        • Engine revision ae90085a84
        • Dart version 2.10.4
    
    [√] Android toolchain - develop for Android devices (Android SDK version 30.0.3) 
        • Android SDK at C:\Users\sonic\AppData\Local\Android\sdk
        • Platform android-30, build-tools 30.0.3
        • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java       
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
        • All Android licenses accepted.
    
    [!] Android Studio (version 4.1.0)
        • Android Studio at C:\Program Files\Android\Android Studio
        X Flutter plugin not installed; this adds Flutter specific functionality.
        X Dart plugin not installed; this adds Dart specific functionality.
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    
    [√] VS Code (version 1.52.1)
        • VS Code at C:\Users\sonic\AppData\Local\Programs\Microsoft VS Code
        • Flutter extension version 3.18.1
    
    [√] Connected device (1 available)
        • SM G950F (mobile) • ce031713eb22600102 • android-arm64 • Android 9 (API 28)
    
    ! Doctor found issues in 1 category.
    

    Additional context I have discussed this issue in person with @felangel.

    bug 
    opened by jeroen-meijer 3
  • Documentation on screen arguments

    Documentation on screen arguments

    This is not a feature request but a documentation request - it would be very helpful to have documentation or examples demonstrating passing data from one page to the next when FlowBuilder is used as the navigation scheme between those pages.

    With the Navigator 1.0 API in Flutter were was an optional argument for passing an "arguments" Object to a named route: https://api.flutter.dev/flutter/widgets/Navigator/pushNamed.html.

    Ideally the same mechanism would be used if deep linking to a page - if the page requires some minimum set of arguments, what is the best way to inject them using FlowBuilder?

    Thank you for your consideration!

    documentation 
    opened by danallen88 0
  • Comparison with go_router, etc.

    Comparison with go_router, etc.

    I like flow_builder very much but wonder whether I'm misusing it - I'm using a single flow to control the whole app navigation. Is this OK to do or should I be using something like https://pub.dev/packages/go_router for general navigation?

    question 
    opened by xni06 0
  • Popping the last page of the flow should complete the flow

    Popping the last page of the flow should complete the flow

    Is your feature request related to a problem? Please describe. Since using Navigator.pop() goes back in the flow, it would be nice if this remains consistent even when the flow only has one page. I would expect popping the last page to complete the flow.

    Having the above functionality makes nesting FlowBuilders very convenient.

    Example
    import 'package:flow_builder/flow_builder.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MaterialApp(home: _HomeFlow()));
    }
    
    enum _HomeFlowState {
      home,
      settings,
    }
    
    class _HomeFlow extends StatelessWidget {
      const _HomeFlow({Key? key}) : super(key: key);
    
      static List<Page> _onGeneratePages(_HomeFlowState state, List<Page> pages) {
        switch (state) {
          case _HomeFlowState.home:
            return [_HomePage.page()];
          case _HomeFlowState.settings:
            return [_HomePage.page(), _SettingsFlow.page()];
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return const FlowBuilder(
          state: _HomeFlowState.home,
          onGeneratePages: _onGeneratePages,
        );
      }
    }
    
    class _HomePage extends StatelessWidget {
      const _HomePage({Key? key}) : super(key: key);
    
      static Page<void> page() => const MaterialPage<void>(child: _HomePage());
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            actions: [
              IconButton(
                onPressed: () => context
                    .flow<_HomeFlowState>()
                    .update((_) => _HomeFlowState.settings),
                icon: const Icon(Icons.settings),
              ),
            ],
          ),
          body: const Center(child: Text('home')),
        );
      }
    }
    
    enum _SettingsFlowState {
      settings,
      about,
      support,
    }
    
    class _SettingsFlow extends StatelessWidget {
      const _SettingsFlow({Key? key}) : super(key: key);
    
      static Page<void> page() => const MaterialPage<void>(child: _SettingsFlow());
    
      static List<Page> _onGeneratePages(
          _SettingsFlowState state, List<Page> pages) {
        switch (state) {
          case _SettingsFlowState.settings:
            return [_SettingsPage.page()];
          case _SettingsFlowState.about:
            return [_SettingsPage.page(), _AboutPage.page()];
          case _SettingsFlowState.support:
            return [_SettingsPage.page(), _SupportPage.page()];
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return const FlowBuilder(
          state: _SettingsFlowState.settings,
          onGeneratePages: _onGeneratePages,
        );
      }
    }
    
    class _SettingsPage extends StatelessWidget {
      const _SettingsPage({Key? key}) : super(key: key);
    
      static Page<void> page() => const MaterialPage<void>(child: _SettingsPage());
    
      @override
      Widget build(BuildContext context) {
       // Native pop should also complete the flow.
        return Scaffold(
          appBar: AppBar(
            leading: BackButton(onPressed: () => Navigator.of(context).pop()), // Should complete the flow
            title: const Text('Settings'),
          ),
          body: Center(
            child: Column(
              children: [
                TextButton(
                  onPressed: () => context
                      .flow<_SettingsFlowState>()
                      .update((_) => _SettingsFlowState.about),
                  child: const Text('About'),
                ),
                TextButton(
                  onPressed: () => context
                      .flow<_SettingsFlowState>()
                      .update((_) => _SettingsFlowState.support),
                  child: const Text('Support'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class _AboutPage extends StatelessWidget {
      const _AboutPage({Key? key}) : super(key: key);
    
      static Page<void> page() => const MaterialPage<void>(child: _AboutPage());
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('About')),
          body: const Center(child: Text('About')),
        );
      }
    }
    
    class _SupportPage extends StatelessWidget {
      const _SupportPage({Key? key}) : super(key: key);
    
      static Page<void> page() => const MaterialPage<void>(child: _SupportPage());
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Support')),
          body: const Center(child: Text('Support')),
        );
      }
    }
    

    Describe the solution you'd like I would like to have some logic that makes the flow complete whenever the last page of the flow is popped.

    Describe alternatives you've considered N/A

    Additional context N/A

    opened by alestiago 0
  • Consider using back_button_interceptor

    Consider using back_button_interceptor

    Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] Currently flow_builder implementation has a conflict with packages that use the back_button_interceptor package, because both use the method SystemChannels.navigation.setMethodCallHandler to listen to navigation events. This causes the onGeneratePages callback to no longer being called on android back button navigation in certain scenarios.

    Describe the solution you'd like A clear and concise description of what you want to happen. As the implementation of back_button_interceptor is lightweight and stable (nearly no open issues, version 6), I propose using it instead of relying on the own interceptor implementation. This resolves any conflicts and results in less code to maintain for flow_builder.

    Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered. Sadly, I was unable to find a solution to merge to calls to the SystemChannels.navigation.setMethodCallHandler API. If that is somehow possible, this would also be a viable option.

    Additional context Add any other context or screenshots about the feature request here. I discovered the bug when working with the loader_overlay package. Initially I filled a bug report there. After discovering the conflict, I filled a bug report with back_button_interceptor here. The maintainer confirmed the conflict, but declined to work on a possible solution, as they are not using flow_builder.

    opened by flodaniel 0
  • Generated Route Access With Flow Builder

    Generated Route Access With Flow Builder

    I'm new to this package, I have nested routes with Authentication and many many blocs and i use Generated Route Access

    Generated Route

    class AppRouter {
      AppRouter();
      static final loginBloc = LoginCubit(
        authBloc: authBloc,
      );
     static final authBloc = AuthBloc();
      static const String home = '/';
      static const String login = 'login';
      static const String profile = '/profile';
    Route<dynamic> onGenerateRoute(RouteSettings settings) {
        switch (settings.name) {
          /// Auth
          case home:
          case login:
            return MaterialPageRoute<dynamic>(
              builder: (_) => MultiBlocProvider(
                providers: [
                  BlocProvider<AuthBloc>.value(
                    value: authBloc,
                  ),
                  BlocProvider<LoginCubit>.value(
                    value: loginBloc,
                  ),
                ],
                child: const AuthFlow(),
              ),
            );
    
          /// Profile
          case profile:
            return MaterialPageRoute<dynamic>(
              builder: (_) => MultiBlocProvider(
                providers: [
                  BlocProvider<AuthBloc>.value(
                    value: authBloc,
                  ),
                ],
                child: const ProfilePage(),
              ),
            );
    }
    
    

    i use Flow Builder in Authentication

    class AuthFlow extends StatelessWidget {
      const AuthFlow({super.key});
      @override
      Widget build(BuildContext context) {
        return FlowBuilder<AuthState>(
          state: context.select((AuthBloc state) => state.state),
          onGeneratePages: (projectState, pages) {
            if (projectState.status == AuthenticationStatus.authenticated) {
              context.read<ProjectBloc>().add(const GetListProject());
              context.read<NewsBloc>().add(const GetList());
            }
            return [
              if (projectState.status == AuthenticationStatus.authenticated)
                const MaterialPage<dynamic>(child: HomePage())
              else
                const MaterialPage<dynamic>(child: LoginPage()),
            ];
          },
        );
      }
    }
    
    

    But inside the HomePage when i go to the profile this error appears

    Navigation Code Navigator.of(context).pushNamed(AppRouter.profile);

    Error Code Navigator.onGenerateRoute was null, but the route named "/profile" was referenced. To use the Navigator API with named routes (pushNamed, pushReplacementNamed, or pushNamedAndRemoveUntil), the Navigator must be provided with an onGenerateRoute handler.

    Is there another way to use the library with Generated Route?

    opened by mstfkhazaal 0
  • feat: url routing and deep linking support

    feat: url routing and deep linking support

    Status

    IN DEVELOPMENT

    Breaking Changes

    NO

    Description

    • feat: url routing and deep linking support (closes #41)

    Type of Change

    • [X] ✨ New feature (non-breaking change which adds functionality)
    • [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
    • [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
    • [ ] 🧹 Code refactor
    • [ ] ✅ Build configuration change
    • [ ] 📝 Documentation
    • [ ] 🗑️ Chore
    • [ ] 🧪 Testing
    enhancement 
    opened by felangel 5
Releases(v0.0.9)
  • v0.0.9(May 31, 2022)

    What's Changed

    • fix: cannot pop with Android back button by @wolfenrain in https://github.com/felangel/flow_builder/pull/89

    New Contributors

    • @wolfenrain made their first contribution in https://github.com/felangel/flow_builder/pull/89

    Full Changelog: https://github.com/felangel/flow_builder/compare/v0.0.8...v0.0.9

    Source code(tar.gz)
    Source code(zip)
  • v0.0.8(May 12, 2022)

  • v0.0.7(May 11, 2022)

  • v0.0.6(Nov 12, 2021)

  • v0.0.5(Nov 3, 2021)

    • BREAKING: refactor: FlowController.state setter removed in favor of update (#61)
    • fix: FlowController notification updates to improve back/forth navigation via BackButton (#61)
    • fix: intellisense on update to include state argument (#64)
      • introduce FlowCallback typedef to improve readability and reusability
      • Thanks @narcodico for the contribution
    • fix: intellisense on OnGeneratePages (#72)
    Source code(tar.gz)
    Source code(zip)
  • v0.0.4(Aug 4, 2021)

  • v0.0.3(Jun 29, 2021)

  • v0.0.2(Apr 5, 2021)

    • fix: don't lose system push events and pass them to WidgetsBindings
    • fix: android back button pops the whole flow instead of popping pushed routes
    • feat: add web/desktop support to example app
    Source code(tar.gz)
    Source code(zip)
  • v0.0.1(Feb 22, 2021)

    • BREAKING: feat!: added support for null-safety
    • feat: FlowBuilder supports List<NavigatorObserver>
    • docs: update example to include custom page transitions
    • docs: update example to include hero animations
    Source code(tar.gz)
    Source code(zip)
  • v0.0.1-dev.13(Jan 23, 2021)

    • fix: invoke SystemNavigator.pop() when FlowBuilder is at root
      • fixes cases where system back button presses result in a black screen on Android
    Source code(tar.gz)
    Source code(zip)
  • v0.0.1-dev.12(Jan 14, 2021)

  • v0.0.1-dev.11(Dec 4, 2020)

  • v0.0.1-dev.10(Dec 1, 2020)

    • BREAKING feat!: remove Update and Complete typedefs
    • feat: update FlowController to have a public constructor
    • feat: FlowBuilder requires either state or controller
    • feat: FlowController exposes state, addListener, removeListener, and dispose
    • fix: support hardware back functionality on Android within nested flows
    • docs: update README to include additional information around FlowController usage
    Source code(tar.gz)
    Source code(zip)
  • v0.0.1-dev.9(Dec 1, 2020)

  • v0.0.1-dev.8(Nov 11, 2020)

  • v0.0.1-dev.7(Nov 6, 2020)

  • v0.0.1-dev.6(Nov 2, 2020)

  • v0.0.1-dev.5(Oct 29, 2020)

  • v0.0.1-dev.4(Oct 29, 2020)

  • v0.0.1-dev.3(Oct 29, 2020)

  • v0.0.1-dev.2(Oct 14, 2020)

  • v0.0.1-dev.1(Oct 14, 2020)

Owner
Felix Angelov
software engineer by day, software engineer by night.
Felix Angelov
Flutter Navigation Best Practices including adapting navigation to platform and branding techniques for navigation surfaces.

Flutter Navigation Best Practices including adapting navigation to platform and branding techniques for navigation surfaces.

Fred Grott 5 Aug 22, 2022
A Flutter package for easy implementation of curved navigation bar

curved_navigation_bar pub package A Flutter package for easy implementation of curved navigation bar. Add dependency dependencies: curved_navigation

null 556 Dec 9, 2022
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named parameters and clear route definitions.

English | Português The brightest, hippest, coolest router for Flutter. Features Simple route navigation Function handlers (map to a function instead

Luke Pighetti 3.5k Jan 4, 2023
Easy-to-use Navigator 2.0 router for web, mobile and desktop. URL-based routing, simple navigation of tabs and nested routes.

Routemaster Hello! Routemaster is an easy-to-use router for Flutter, which wraps over Navigator 2.0... and has a silly name. Features Simple declarati

Tom Gilder 291 Jan 3, 2023
A flutter navigation package

Create By Me(Agalaba Ifeanyi Precious) go Navigate Navigate Like a pro from one Screen to another Using go navigate. go_Navigate provide you the abili

Agalaba Ifeanyi Precious 2 Oct 11, 2021
A Flutter package for easily implementing Material Design navigation transitions.

Morpheus A Flutter package for easily implementing Material Design navigation transitions. Examples Parent-child transition You can use MorpheusPageRo

Sander R. D. Larsen 186 Jan 7, 2023
Transparent Android system navigation bar with Flutter and FlexColorScheme package.

Sysnavbar with FlexColorScheme Transparent Android system navigation bar with Flutter and FlexColorScheme. FlexColorScheme V4 Notice If you are using

Rydmike 12 Oct 21, 2022
Elegant abstraction for complete deep linking navigation in Flutter

Flutter Deep Link Navigation Provides an elegant abstraction for complete deep linking navigation in Flutter. This package only provides deep linking

Dennis Krasnov 64 Dec 27, 2022
A Flutter implementation of a customizable navigation bar with animations.

A heavily customizable bottom navigation bar with some animation modifiers.

null 1 Jun 17, 2022
flutter bottom navigation bat project

bottom_navigation A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you starte

Danushan Ravendran 3 Sep 23, 2021
Fast code and awesome design-ui for flutter navigation bar

Flutter-awesome-bottom-navigation-bar ??‍?? Fast code and awesome design-ui for flutter navigation bar ?? Getting Started # First you need to add flas

Hmida 20 Nov 22, 2022
Custom Bottom navigation bar on Flutter.

Intro Custom Bottom navigation bar on Flutter. The updated one Support : Null safety & Support 9 items on Tabs & Some Color, Size, Effects and font cu

Ihab Zaidi 2 Oct 8, 2021
Flutter Material Design Navigation Drawer Menu

navigation_drawer_menu Flutter Material Design Navigation Drawer Menu Navigation drawer is a common UI pattern for adaptive menus. The Material Design

Christian Findlay 9 Dec 12, 2022
Customized 🚀 Bottom Navigation Bar Using Flutter 🐦

Customized ?? Bottom Navigation Bar Using Flutter ??

AmirHossein Bayat 3 Dec 7, 2022
Flutter custom BottomBar Navigation Widget

bottom_bar_with_sheet ?? Non-standard way to use more space of screens in your application ?? ?? Custom bottom Sheet under Bottom Navigation Bar ?? ??

Stanislav Ilin 305 Dec 23, 2022
Simple but powerfull Flutter navigation with riverpod and Navigator 2.0

Riverpod navigation If you are interested in the motivation why the package was created and a detailed description of what problems it solves, read th

pavelpz 20 Dec 13, 2022
Persistent Bottom Navigation Bar

Persistent Bottom Navigation Bar A persistent/static bottom navigation bar for Flutter. NOTE: Those migrating from pre 2.0.0 version should check the

Bilal Shahid 421 Dec 20, 2022
A bottom navigation bar that you can customize with the options you need, without any limits.

Bottom Personalized Dot Bar A bottom navigation bar that you can customize with the options you need, without any limits. You can also customize the a

null 103 Oct 20, 2022
A Custom Extended Scaffold with Expandable and Floating Navigation Bar

Custom Extended Scaffold Custom Flutter widgets that makes Bottom Navigation Floating and can be expanded with much cleaner a

Ketan Choyal 139 Dec 10, 2022