Skip to content

Conversation

@goderbauer
Copy link
Member

@goderbauer goderbauer commented Sep 25, 2020

Description

Prior to this change, the MaterialPage and CupertinoPage would take a builder, which was a footgun:

class _KeepsStateTestWidgetState extends State<KeepsStateTestWidget> {
  String _subpage = 'subpage';

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: Navigator(
        key: widget.navigatorKey,
        pages: <Page<void>>[
          const CupertinoPage<void>(builder: (BuildContext context) => Text('home')),
          if (_subpage != null) CupertinoPage<void>((BuildContext context) => Text(_subpage)),
        ],
        onPopPage: (Route<dynamic> route, dynamic result) {
          if (!route.didPop(result)) {
            return false;
          }
          setState(() {
            _subpage = null;
          });
          return true;
        },
      ),
    );
  }
}

When the second page is transitioning out, _subpage is set to null. Because the Navigator is rebuild, it would rebuild all its routes as well with that the builder of the second executes again, rebuilding itself with _subpage == null, which is not what people want.

This PR changes the API of CupertinoPage and MaterialPage. Instead of taking a builder, it takes a prebuild child widget to avoid this problem.

This PR also removes the CustomBuilderPage and TransitionBuilderPage. We can come up with a version of them that doesn't rely on builders in the future.

Related Issues

Fixes #66695.

Tests

I added the following tests:

  • Updated existing tests
  • Added tests to verify that pages don't loose their state when popped.

Checklist

Before you create this PR, confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

@flutter-dashboard flutter-dashboard bot added f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Sep 25, 2020
@goderbauer goderbauer requested a review from chunhtai September 25, 2020 22:50
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chunhtai
Copy link
Contributor

internal test failure, looks like some projects have started using the materialPage class.

@fluttergithubbot fluttergithubbot merged commit 062e469 into flutter:master Sep 27, 2020
@goderbauer goderbauer deleted the childPages branch September 27, 2020 22:41
@goderbauer
Copy link
Member Author

cl/334055440 fixes google testing for this PR.

goderbauer added a commit to goderbauer/flutter that referenced this pull request Sep 28, 2020
christopherfujino pushed a commit to chris-forks/flutter that referenced this pull request Sep 28, 2020
christopherfujino added a commit that referenced this pull request Sep 29, 2020
* [Icons][iOS] Pointing to version of material icon font that includes more metadata in the xml. (#66684)
* apply engine cherrypicks
* Page-subclasses to take children instead of builder (#66694)
* Update pub dependencies to support dart 2.10.0
* cherry-pick 76ad864
* Fix the inconsistency between the local state of the input and the engine state (#65754)

Co-authored-by: Will Larche <larche@google.com>
Co-authored-by: Michael Goderbauer <goderbauer@google.com>
Co-authored-by: xubaolin <xubaolin@oppo.com>
@acoutts
Copy link

acoutts commented Oct 1, 2020

What should we use in place of TransitionBuilderPage?

@goderbauer
Copy link
Member Author

goderbauer commented Oct 1, 2020

You can define your own Page subclass that in createRoute returns a PageRouteBuilder.

willlockwood pushed a commit to willlockwood/flutter that referenced this pull request Dec 25, 2020
* [Icons][iOS] Pointing to version of material icon font that includes more metadata in the xml. (flutter#66684)
* apply engine cherrypicks
* Page-subclasses to take children instead of builder (flutter#66694)
* Update pub dependencies to support dart 2.10.0
* cherry-pick 76ad864
* Fix the inconsistency between the local state of the input and the engine state (flutter#65754)

Co-authored-by: Will Larche <larche@google.com>
Co-authored-by: Michael Goderbauer <goderbauer@google.com>
Co-authored-by: xubaolin <xubaolin@oppo.com>
thanhle1547 added a commit to thanhle1547/flutter_simple_app_router that referenced this pull request Jul 18, 2025
…d of a builder function to not delay widget creation

related:
flutter/flutter#66694
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Builders of MaterialPage and CupertinoPage are a footgun

5 participants