Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[framework] re-rasterize when window size or insets changes #113647

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

Merged
merged 13 commits into from
Oct 24, 2022
Merged
33 changes: 33 additions & 0 deletions packages/flutter/lib/src/material/page_transitions_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr
bool get useSnapshot => !kIsWeb && widget.allowSnapshotting;

late _ZoomEnterTransitionPainter delegate;
MediaQueryData? mediaQueryData;

static final Animatable<double> _fadeInTransition = Tween<double>(
begin: 0.0,
Expand Down Expand Up @@ -355,6 +356,18 @@ class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> with _ZoomTr
super.didUpdateWidget(oldWidget);
}

@override
void didChangeDependencies() {
// If the screen size changes during the transition, perhaps due to
// a keyboard dismissal, then ensure that contents are re-rasterized once.
final MediaQueryData? data = MediaQuery.maybeOf(context);
if (mediaQueryDataChanged(mediaQueryData, data)) {
controller.clear();
}
mediaQueryData = data;
super.didChangeDependencies();
}

@override
void dispose() {
widget.animation.removeListener(onAnimationValueChange);
Expand Down Expand Up @@ -394,6 +407,7 @@ class _ZoomExitTransition extends StatefulWidget {

class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTransitionBase {
late _ZoomExitTransitionPainter delegate;
MediaQueryData? mediaQueryData;

// See SnapshotWidget doc comment, this is disabled on web because the HTML backend doesn't
// support this functionality and the canvaskit backend uses a single thread for UI and raster
Expand Down Expand Up @@ -458,6 +472,18 @@ class _ZoomExitTransitionState extends State<_ZoomExitTransition> with _ZoomTran
super.didUpdateWidget(oldWidget);
}

@override
Copy link
Member

Choose a reason for hiding this comment

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

Instead of duplicating this, could it have been implemented in the _ZoomTransitionBase if that mixin were to be made a mixin on State?

void didChangeDependencies() {
// If the screen size changes during the transition, perhaps due to
// a keyboard dismissal, then ensure that contents are re-rasterized once.
final MediaQueryData? data = MediaQuery.maybeOf(context);
if (mediaQueryDataChanged(mediaQueryData, data)) {
controller.clear();
}
mediaQueryData = data;
super.didChangeDependencies();
}

@override
void dispose() {
widget.animation.removeListener(onAnimationValueChange);
Expand Down Expand Up @@ -804,6 +830,13 @@ mixin _ZoomTransitionBase {
break;
}
}

// Whether any of the properties that would impact the page transition
// changed.
bool mediaQueryDataChanged(MediaQueryData? oldData, MediaQueryData? newData) {
return oldData?.size != newData?.size ||
oldData?.viewInsets != newData?.viewInsets;
}
}

class _ZoomEnterTransitionPainter extends SnapshotPainter {
Expand Down
43 changes: 43 additions & 0 deletions packages/flutter/test/material/page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@Tags(<String>['reduced-test-set'])
import 'package:flutter/cupertino.dart' show CupertinoPageRoute;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -234,6 +236,47 @@ void main() {
expect(find.text('Page 2'), findsNothing);
}, variant: TargetPlatformVariant.only(TargetPlatform.android));

testWidgets('test page transition (_ZoomPageTransition) with rasterization re-rasterizes when window size changes', (WidgetTester tester) async {
// Shrink the window size.
late Size oldSize;
try {
oldSize = tester.binding.window.physicalSize;
tester.binding.window.physicalSizeTestValue = const Size(1000, 1000);

final Key key = GlobalKey();
await tester.pumpWidget(
RepaintBoundary(
key: key,
child: MaterialApp(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
builder: (BuildContext context) {
return const Material(child: SizedBox.shrink());
},
);
},
),
),
);

tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
await tester.pump();
await tester.pump(const Duration(milliseconds: 50));

await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.small.png'));

// Increase the window size.
tester.binding.window.physicalSizeTestValue = const Size(1000, 2000);

await tester.pump();
await tester.pump(const Duration(milliseconds: 50));

await expectLater(find.byKey(key), matchesGoldenFile('zoom_page_transition.big.png'));
} finally {
tester.binding.window.physicalSizeTestValue = oldSize;
}
}, variant: TargetPlatformVariant.only(TargetPlatform.android), skip: kIsWeb); // [intended] rasterization is not used on the web.

testWidgets('test fullscreen dialog transition', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
Expand Down