Skip to content

Conversation

@QuncCccccc
Copy link
Contributor

@QuncCccccc QuncCccccc commented Nov 13, 2024

This PR is to add a new page transition for Material 3.

The new builder matches the latest Android page transition behavior; while the new page slides in from right to left, it fades in at the same time and the old page slides out from right to left, fading out at the same time. When both pages are fading in/out, the black background might show up, so I added a ColoredBox for the slides-out page whose color defaults to ColorScheme.surface. The backgroundColor property can be used to customize the default transition color.

This demo shows the forward and backward behaviors.

page_transition.mov

Fixes: #142352

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Nov 13, 2024
@github-actions github-actions bot added a: text input Entering text in a text field or keyboard related problems d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos a: tests "flutter test", flutter_test, or one of our tests f: routes Navigator, Router, and related APIs. f: scrolling Viewports, list views, slivers, etc. labels Nov 17, 2024
@QuncCccccc QuncCccccc marked this pull request as ready for review November 19, 2024 20:55
Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

Looks really good on a first pass! I'm wondering about migrating to this new transition being the default though. I think some of the Google testing might be difficult to adjust in one go.

final TargetPlatform platform = Theme.of(context).platform;
final PageTransitionsTheme pageTransitionsTheme = Theme.of(context).pageTransitionsTheme;
final PageTransitionsBuilder? pageTransitionBuilder = pageTransitionsTheme.builders[platform];
return pageTransitionBuilder is FadeForwardsPageTransitionsBuilder
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the duration be a property of the page transition builders? If we add more transitions, I could see this continuing to be an issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated! Thanks!


static const Map<TargetPlatform, PageTransitionsBuilder> _defaultBuilders = <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(),
TargetPlatform.android: FadeForwardsPageTransitionsBuilder(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make this transition the default right away? I'm guessing this is what's breaking Google testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. The google testing failures are related to the updated behaviors like the duration change and the added ColoredBox. Maybe we can use useMaterial3 to control the default? But it also defaults to true now so using it won't fix the google testing. A migration guide and an announcement are probably also needed:)

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we maybe add the builder as an option in this PR but not make it the default? Then put out an announcement that we are going to transfer over to this new transition being the default, and if they want to opt out ahead of time they can set the zoom transition as their default in their theme. Then they could either, switch to using it early and migrate their tests themselves, explicitly set the zoom transition builder in their themes for all platforms needed, or let it merge later and break their tests, but they'll have warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I think this can help land the change in a soft breaking manner😄! Let me separate this PR.

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.

overal LGTM,

I also vaguely remember @jonahwilliams mentioned some performance issue with old transition. will the issue still persist after the change?

theme: ThemeData(
pageTransitionsTheme: PageTransitionsTheme(
builders: Map<TargetPlatform, PageTransitionsBuilder>.fromIterable(
TargetPlatform.values, value: (_) => const FadeForwardsPageTransitionsBuilder()
Copy link
Contributor

Choose a reason for hiding this comment

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

in example page_transition_theme.0.dart, there was a comment said the default is FadeForwardsPageTransitionsBuilder if not specify, is this override needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If not specify, I think on iOS and macOS platforms, it will default to CupertinoPageTransitionsBuilder(), and in this example, I just wanted to show the new page transition, so I just override everything. Do you think if this is necessary?

Copy link
Contributor

Choose a reason for hiding this comment

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

Then I think the comment in page_transition_theme.0.dart should be updated as the default may not always be FadeForwardsPageTransitionsBuilder when unspecified.


import 'package:flutter/material.dart';

/// Flutter code sample for [PageTransitionsTheme].
Copy link
Contributor

Choose a reason for hiding this comment

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

This can use some more explanation. I assume this is to show case the new material transition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, just updated! Thanks!

expect(find.byType(FlutterLogo), findsOneWidget);
expect(find.byType(Padding), findsAtLeast(1));
expect(find.byType(SlideTransition), findsOneWidget);
expect(find.byType(SlideTransition), findsAtLeast(1));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The new page transition also uses SlideTransition, so there are more than one in this example.

final TargetPlatform platform = Theme.of(context).platform;
final PageTransitionsTheme pageTransitionsTheme = Theme.of(context).pageTransitionsTheme;
final PageTransitionsBuilder? pageTransitionBuilder = pageTransitionsTheme.builders[platform];
return pageTransitionBuilder is FadeForwardsPageTransitionsBuilder
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
final PageTransitionsTheme theme = Theme.of(context).pageTransitionsTheme;
final Duration duration = _getTransitionDuration(context);
controller?.duration = duration;
Copy link
Contributor

Choose a reason for hiding this comment

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

After I thinking about it more, I think it should be done in TransitionRoute.didPush and didPop() to update the duration and reverseDuration directly right before forward() and reverse() is called.

That way you don't need this logic here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated! Thanks!

/// helps avoid a black background between two page.
///
/// Defaults to [ColorScheme.surface]
final Color? backgroundColor;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have use case where people want to set a different color other than surface? it seems whichever color they pick will cause a color flash

Copy link
Contributor Author

@QuncCccccc QuncCccccc Nov 21, 2024

Choose a reason for hiding this comment

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

I think so! If the page has its own color(not ColorScheme.surface), changing the backgroundColor to the same color can avoid the color flash. I noticed this problem in page_transition_theme.0.dart, the two pages has their own Scaffold.backgroundColor, the first page has blueGrey as its background, so if we want to use the new builder and no color flash, we should also set the background color to Colors.blueGrey.

/// that's similar to the one provided by Android O.
/// * [OpenUpwardsPageTransitionsBuilder], which defines a page transition
/// that's similar to the one provided by Andoird P.
/// * [ZoomPageTransitionsBuilder], which defines the default page transition
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are going to keep the old transition, have we thought about having android version as part of theme? for example

ThemeData.androidVersion, and then based on version we build different default pagetransition

Copy link
Contributor Author

@QuncCccccc QuncCccccc Nov 21, 2024

Choose a reason for hiding this comment

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

I actually think we should not encourage users to use the old page transitions and should deprecate those in the future, as they are already outdated:)

@jonahwilliams
Copy link
Contributor

The performance problem was due to the scaling factor which is absent from this transition AFAIK.

@github-actions github-actions bot removed a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems f: scrolling Viewports, list views, slivers, etc. f: routes Navigator, Router, and related APIs. labels Nov 21, 2024
@QuncCccccc QuncCccccc changed the title Update Android default page transition Create new page transition for M3 Nov 21, 2024

@override
TickerFuture didPush() {
controller?.duration = transitionDuration;
Copy link
Contributor

Choose a reason for hiding this comment

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

not in this class, I meant in TransitionRoute class directly

TickerFuture didPush() {

@github-actions github-actions bot added the f: routes Navigator, Router, and related APIs. label Nov 22, 2024
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

Copy link
Contributor

@MitchellGoodwin MitchellGoodwin left a comment

Choose a reason for hiding this comment

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

LGTM!

await tester.tap(find.text('pop'));
await tester.pump(const Duration(milliseconds: 299));
expect(find.text('page b'), findsOneWidget);
expect(find.byType(ColoredBox), findsNothing); // ColoredBox doesn't exist in CupertinoPageTransition.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Should this comment say FadeUpwardsPageTransition instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah thanks for catching this! Updated:)

@QuncCccccc
Copy link
Contributor Author

Oh seems the last commit caused some test failures related to bottom sheet animation. Taking a look.

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 9, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 9, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 10, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
@reidbaker reidbaker mentioned this pull request Dec 13, 2024
11 tasks
nick9822 pushed a commit to nick9822/flutter that referenced this pull request Dec 18, 2024
…e transition. (flutter/engine#56762)

For flutter#158881

The new Android m3 page transition animates a saveLayer w/ opacity + slide in animation. See example video from linked PR:

https://github.com/user-attachments/assets/1382374a-4e0c-4a0e-9d70-948ce12e6298

On each frame, we intersect the coverage rect of this saveLayer contents with the screen rect, and shrink it to a partial rectangle. But this changes each frame, which forces us to re-allocate a large texture each frame, causing performance issues.

Why not ignore the cull rect entirely? We sometimes ignore the cull rect for the image filter layer for similar reasons, but from observation, the sizes of these saveLayer can be slightly larger than the screen for flutter gallery. Instead, I attempted to use the cull rect size to shrink the saveLayer by shifting the origin before intersecting.

I think this should be safe to do, as I believe it could only leave the coverage as larger than it would have been and not smaller.
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 12, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 6, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos 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.

The default Android page transition is not up to date for M3.

5 participants