-
Notifications
You must be signed in to change notification settings - Fork 26.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Material App is complicated/confusing #140762
Comments
Navigator
From MaterialApp
MaterialApp
Without it's Nav Logic
I wonder if there is a way to have the existing constructor more or less work the same by implicitly wrapping and we create a new constructor without any navigation logic, basically option 3 without a breaking change: class MaterialApp {
factory MaterialApp(/*existing args*/) {
return _ImplicitNavMaterialApp(...);
}
factory MaterialApp.withoutNavigation(/**/) {
// TODO: Implement.
}
} Based on reception/feedback we could either rename constructors in the future, or even have some sort of auto-fix that inlines the default constructor for users. |
i use go_router for navigation . how can i use go_router with proposals 3 !!!! |
@samithe7 I haven't used FWIW It occurs to me the problem here might be one more of API discovery than anything else. So right now the best workaround (which I am already using) I'd still have to use under proposals 2 and 3. This makes option 1 sound a lot more appealing. Here's "option 2b" with this in mind: I like that this approach gives the developer arbitrary navigation flexibility while guiding them through the process of binding their custom solution to the system back gesture. But it's still a little awkward. Namely, |
To answer the request made in the title of this issue: It is already today possible to use |
MaterialApp
Without it's Nav Logic
I would like to provide further insight from my experience. As was already mentioned and I agree, both I think Navigation should be opt in and a responsibility of the consumer of the API. What if I don't want a navigator at all and I just want a single page application? What if I want nested navigators? Most of the times navigation is gradual, meaning that you start with a simple navigation flow, consisting of a couple of pages. Then you realize you want parallel navigation histories, where you introduce nested navigators with the top one orchestrating which one is active. After that, you may want to add a loading or a sign in flow before the nested navigator. To conclude, I think navigation should be a separate issue not a responsibility of the top level widget. This would unlock many possibilities of independent evolution. It is the same as the implicit/explicit view in a multiview app, that is coming soon. Implicit is good for faster development, but explicitly manifesting the view hierarchy is a must for more advanced usecases. |
@caseycrogers In my application, I disabled title bar of window and use Widget builder(BuildContext context, Widget? child) {
return Column(
children: [
if (Platform.isWindows || Platform.isMacOS) const WindowAppBar(),
Expanded(child: ClipRRect(child: child)),
],
);
} It's a good example to explain what Colunm(
children: [
if (Platform.isWindows || Platform.isMacOS) const WindowAppBar(),
Expanded(child: ClipRRect(child: MaterialApp(...))),
],
); Instead, using the example code as above, |
Use case
MaterialApp
wraps the tree in a navigator/router (transitively viaWidgetsApp
). Since there are so many different approaches to navigation now (Nav 1, Nav 2, GoRouter, Nav 1 router based, etc) this massively balloonsMaterialApp
's constructor. Not to mention,MaterialApp
breaks Nav 2 on Android (system back closes the entire app) and requires a workaround to use.Here is a list of navigation related constructor arguments in
MaterialApp
:navigatorKey
home
- this would probably just be replaced bychild
if nav logic were removedinitialRoute
onGenerateRoute
onGenerateInitialRoutes
onNavigationNotification
navigatorObservers
Then there's the entire
MaterialApp.router
alternate constructor.Many of these args have non-obvious runtime constraints too:
flutter/packages/flutter/lib/src/material/app.dart
Line 199 in 3df4e73
And, since most of these arguments are just proxies for
WidgetApps
/Router
/Navigator
, they're a maintenance burden to keep in sync, have unreadable inline docs (may depend on IDE settings), and their logic is hard to trace when clicking through the source code:Proposal
Handling navigation logic in
MaterialApp
made sense when Flutter's navigation options were simple and limited. We are well past that point.Here are a couple proposals of various levels of disruption that would resolve this problem. Note that all of these proposals probably involve modifying
WidgetsApp
to mirror theMaterialApp
changesMaterialApp
will bind the system back gesture to the navigator associated with that key, and provide no other navigation logic of its own. Pros: no disruption, minimal boilerplate. Cons:MaterialApp
becomes more complicated instead of less, would be hard to disambiguate this new arg from the existingnavigatorKey
arg.MaterialApp
remains complicated, developer has to write a fair amount of boilerplate to opt out of material app nav.MaterialApp
. Pros: simplifies dramatically. Cons: high disruption, newbies who would've been happy with basic default behavior now have to write a lot of boilerplate (PopHandler
,Navigator
).3 feels very "pure" but is quite disruptive. 1 feels a little sloppy/awkward. 2 feels like the sweet spot as it both avoids disruption while providing an elegant escape hatch.
Happy to hear your all's thoughts and am more than willing to write the associated PR(s) myself to make any of these 3 happen.
The text was updated successfully, but these errors were encountered: