Skip to content

Create a builder that builds a widget that a wraps routes of Navigator. #34105

Closed

Description

@ivk1800

It is discussion of closed PR #33706

I suggest add add builder wrapper of navigator routers for access Navigator from above routers of widgets tree.
It is allow access to Navigator from root widget and control navigation of application. for example I can create abstract Router for Viewmodel or Presenter and control app routing from logic layer without clearly communication with "View" layer.

you say why not wrap MaterialApp in to RootWidget? but in but in this case I will not have access to MediaQuuery, Navigator etc.

you say why you push to navigator RootRoute as first route and control Navigation from him? because netx routes will be have back arrow on AppBar. And I can accidentally pop her from Navigaton. It is no way.

you say why not create custom App with WidgetApp and Navigator? no way, because I want use all features of MaterialApp or CupertionApp which encapsulated in exist Widget.

below is an example;

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(),
      ),
      navigatorRoutesWrapperBuilder: (BuildContext context, Widget child) {
        return RootWidget(
          child: child,
        );
      },
    );
  }
}

class RootWidget extends StatefulWidget {
  final Widget child;

  RootWidget({Key key, this.child}) : super(key: key);

  @override
  _RootWidgetState createState() => _RootWidgetState();
}

class _RootWidgetState extends State<RootWidget> {

  RootAppBloc _bloc;

  @override
  void initState() {
    _bloc = RootAppBloc();
    super.initState();

    _bloc.pushLoginScreen.listen((_) {
      Route<dynamic> route = MaterialPageRoute<dynamic>(builder: (BuildContext context) {
        return Text('login');
      });

      Navigator.of(context).pushAndRemoveUntil(route, (Route<dynamic> route) {
        return false;
      });
    });

    _bloc.pushMainScreen.listen((_) {
      // some code
    });
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

class RootAppBloc {
  Stream<void> pushMainScreen;
  Stream<void> pushLoginScreen;
}

Activity

  1. added
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    on Jun 8, 2019
  2. jsroest commented on Jan 4, 2020

    @jsroest

    The main reason why I like this idea is that with this solution it is possible to put a DialogManager above each route without an extra/custom navigator.

    https://medium.com/flutter-community/manager-your-flutter-dialogs-with-a-dialog-manager-1e862529523a

  3. added
    f: routesNavigator, Router, and related APIs.
    frameworkflutter/packages/flutter repository. See also f: labels.
    c: proposalA detailed proposal for a change to Flutter
    on Jan 16, 2020
  4. jasonspick commented on Feb 25, 2020

    @jasonspick

    If I am understanding this correctly, this would be the same as Angular's router-outlet concept. We would be able to have a static scaffold that doesn't refresh with every navigation.

    If so, would the possibility of having multiple navigators and outlets?

  5. ivk1800 commented on Apr 25, 2020

    @ivk1800
    ContributorAuthor

    @jsroest your solution on article is not properly work if press back button, it is sadly

  6. Auuufff commented on Apr 29, 2020

    @Auuufff

    It would be nice to have this feature

  7. chunhtai commented on May 28, 2020

    @chunhtai
    Contributor

    you can use the https://master-api.flutter.dev/flutter/material/MaterialApp/builder.html

    If you want access to the navigator, you can provide the navigator key and access it globally. are there any other use cases that cannot be solved by this?

  8. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    and removed
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    on May 28, 2020
  9. jsroest commented on May 29, 2020

    @jsroest

    are there any other use cases that cannot be solved by this?

    I have a dialogService that uses the material.showDialog function provided by the Flutter framework. Unfortunately, you can not pass the NavigatorState directly to this function, but you have to pass a context, so it can do the lookup for the navigator itself. This forces me to declare a dialogService above every page manually.

    The suggested builder would eliminate this repetition.

  10. chunhtai commented on May 29, 2020

    @chunhtai
    Contributor

    are there any other use cases that cannot be solved by this?

    I have a dialogService that uses the material.showDialog function provided by the Flutter framework. Unfortunately, you can not pass the NavigatorState directly to this function, but you have to pass a context, so it can do the lookup for the navigator itself. This forces me to declare a dialogService above every page manually.

    The suggested builder would eliminate this repetition.

    I think not able to use navigator state directly in show dialog is a bug. If we enable that do you think that will solve your use case?

  11. jsroest commented on May 29, 2020

    @jsroest

    are there any other use cases that cannot be solved by this?

    I have a dialogService that uses the material.showDialog function provided by the Flutter framework. Unfortunately, you can not pass the NavigatorState directly to this function, but you have to pass a context, so it can do the lookup for the navigator itself. This forces me to declare a dialogService above every page manually.
    The suggested builder would eliminate this repetition.

    I think not able to use navigator state directly in show dialog is a bug. If we enable that do you think that will solve your use case?

    Yes, that will solve my use case.

  12. jasonspick commented on May 29, 2020

    @jasonspick

    Think web applications

  13. chunhtai commented on May 29, 2020

    @chunhtai
    Contributor

    Think web applications

    If you meant static content above navigator the MaterialApp.builder should work. If you meant nested navigator such as angular router-outlet, we are currently working on that in Navigator 2.0 and router widget

  14. self-assigned this
    on Jun 8, 2020
  15. added and removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jun 8, 2020
  16. marcglasberg commented on May 16, 2021

    @marcglasberg

    To document this:

    If you want to have a "dialog service", put it in your builder:

     MaterialApp(
            navigatorKey: myNavigatorKey,
            builder: (BuildContext context, Widget? child) { 
                 return MyDialogService(child: child)
    },
    

    When you access MyDialogService up in the tree it cannot call showDialog with its own context. But you can use myNavigatorKey.currentContext:

    showDialog(context : myNavigatorKey.currentContext, ...)
    

    @chunhtai Quite frankly, I would prefer we could indeed create a builder that builds a widget that a wraps routes of Navigator. This would be more elegant than using keys (I feel every time we use global keys we have a bad architecture). As pointed out above, this could be used to have a static scaffold that doesn't refresh with every navigation. I believe this would also be a nice place to put custom keyboards, that could use the Navigator to close with the back button. They are an example of a necessary "scaffold" that should exist in every page. Where should I put them instead?

  17. github-actions commented on Aug 1, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  18. locked as resolved and limited conversation to collaborators on Aug 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

c: proposalA detailed proposal for a change to Flutterf: routesNavigator, Router, and related APIs.frameworkflutter/packages/flutter repository. See also f: labels.waiting for PR to land (fixed)A fix is in flight

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions