mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix memory leaks in open upwards page transition (#148046)
This commit is contained in:
parent
de9ca5c1c8
commit
b23f34657e
@ -48,7 +48,7 @@ class _FadeUpwardsPageTransition extends StatelessWidget {
|
||||
}
|
||||
|
||||
// This transition is intended to match the default for Android P.
|
||||
class _OpenUpwardsPageTransition extends StatelessWidget {
|
||||
class _OpenUpwardsPageTransition extends StatefulWidget {
|
||||
const _OpenUpwardsPageTransition({
|
||||
required this.animation,
|
||||
required this.secondaryAnimation,
|
||||
@ -81,37 +81,77 @@ class _OpenUpwardsPageTransition extends StatelessWidget {
|
||||
final Animation<double> secondaryAnimation;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
State<_OpenUpwardsPageTransition> createState() => _OpenUpwardsPageTransitionState();
|
||||
}
|
||||
|
||||
class _OpenUpwardsPageTransitionState extends State<_OpenUpwardsPageTransition> {
|
||||
late CurvedAnimation _primaryAnimation;
|
||||
late CurvedAnimation _secondaryTranslationCurvedAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_setAnimations();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant _OpenUpwardsPageTransition oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.animation != widget.animation ||
|
||||
oldWidget.secondaryAnimation != widget.secondaryAnimation
|
||||
) {
|
||||
_disposeAnimations();
|
||||
_setAnimations();
|
||||
}
|
||||
}
|
||||
|
||||
void _setAnimations() {
|
||||
_primaryAnimation = CurvedAnimation(
|
||||
parent: widget.animation,
|
||||
curve: _OpenUpwardsPageTransition._transitionCurve,
|
||||
reverseCurve: _OpenUpwardsPageTransition._transitionCurve.flipped,
|
||||
);
|
||||
_secondaryTranslationCurvedAnimation = CurvedAnimation(
|
||||
parent: widget.secondaryAnimation,
|
||||
curve: _OpenUpwardsPageTransition._transitionCurve,
|
||||
reverseCurve: _OpenUpwardsPageTransition._transitionCurve.flipped,
|
||||
);
|
||||
}
|
||||
|
||||
void _disposeAnimations() {
|
||||
_primaryAnimation.dispose();
|
||||
_secondaryTranslationCurvedAnimation.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposeAnimations();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final Size size = constraints.biggest;
|
||||
|
||||
final CurvedAnimation primaryAnimation = CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: _transitionCurve,
|
||||
reverseCurve: _transitionCurve.flipped,
|
||||
);
|
||||
|
||||
// Gradually expose the new page from bottom to top.
|
||||
final Animation<double> clipAnimation = Tween<double>(
|
||||
begin: 0.0,
|
||||
end: size.height,
|
||||
).animate(primaryAnimation);
|
||||
).animate(_primaryAnimation);
|
||||
|
||||
final Animation<double> opacityAnimation = _scrimOpacityTween.animate(primaryAnimation);
|
||||
final Animation<Offset> primaryTranslationAnimation = _primaryTranslationTween.animate(primaryAnimation);
|
||||
final Animation<double> opacityAnimation = _OpenUpwardsPageTransition._scrimOpacityTween.animate(_primaryAnimation);
|
||||
final Animation<Offset> primaryTranslationAnimation = _OpenUpwardsPageTransition._primaryTranslationTween.animate(_primaryAnimation);
|
||||
|
||||
final Animation<Offset> secondaryTranslationAnimation = _secondaryTranslationTween.animate(
|
||||
CurvedAnimation(
|
||||
parent: secondaryAnimation,
|
||||
curve: _transitionCurve,
|
||||
reverseCurve: _transitionCurve.flipped,
|
||||
),
|
||||
final Animation<Offset> secondaryTranslationAnimation = _OpenUpwardsPageTransition._secondaryTranslationTween.animate(
|
||||
_secondaryTranslationCurvedAnimation,
|
||||
);
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: animation,
|
||||
animation: widget.animation,
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return Container(
|
||||
color: Colors.black.withOpacity(opacityAnimation.value),
|
||||
@ -129,10 +169,10 @@ class _OpenUpwardsPageTransition extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
child: AnimatedBuilder(
|
||||
animation: secondaryAnimation,
|
||||
animation: widget.secondaryAnimation,
|
||||
child: FractionalTranslation(
|
||||
translation: primaryTranslationAnimation.value,
|
||||
child: child,
|
||||
child: widget.child,
|
||||
),
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return FractionalTranslation(
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
|
||||
@ -97,7 +98,10 @@ void main() {
|
||||
expect(findZoomPageTransition(), findsOneWidget);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
|
||||
|
||||
testWidgets('PageTransitionsTheme override builds a _OpenUpwardsPageTransition', (WidgetTester tester) async {
|
||||
testWidgets('PageTransitionsTheme override builds a _OpenUpwardsPageTransition',
|
||||
// TODO(polina-c): remove when fixed https://github.com/flutter/flutter/issues/145600 [leak-tracking-opt-in]
|
||||
experimentalLeakTesting: LeakTesting.settings.withTracked(classes: const <String>['CurvedAnimation']),
|
||||
(WidgetTester tester) async {
|
||||
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
||||
'/': (BuildContext context) => Material(
|
||||
child: TextButton(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user