mirror of
https://github.com/flutter/flutter
synced 2024-10-02 14:34:22 +00:00
Fix memory leaks in FloatingActionButton
(#146711)
This commit is contained in:
parent
46fbb73440
commit
266cdf0b1e
|
@ -1320,6 +1320,9 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr
|
|||
// The animations applied to the Floating Action Button when it is entering or exiting.
|
||||
// Controls the previous widget.child as it exits.
|
||||
late AnimationController _previousController;
|
||||
CurvedAnimation? _previousExitScaleAnimation;
|
||||
CurvedAnimation? _previousExitRotationCurvedAnimation;
|
||||
CurvedAnimation? _currentEntranceScaleAnimation;
|
||||
late Animation<double> _previousScaleAnimation;
|
||||
late TrainHoppingAnimation _previousRotationAnimation;
|
||||
// The animations to run, considering the widget's fabMoveAnimation and the current/previous entrance/exit animations.
|
||||
|
@ -1352,6 +1355,9 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr
|
|||
@override
|
||||
void dispose() {
|
||||
_previousController.dispose();
|
||||
_previousExitScaleAnimation?.dispose();
|
||||
_previousExitRotationCurvedAnimation?.dispose();
|
||||
_currentEntranceScaleAnimation?.dispose();
|
||||
_disposeAnimations();
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -1402,19 +1408,24 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr
|
|||
}
|
||||
|
||||
void _updateAnimations() {
|
||||
_previousExitScaleAnimation?.dispose();
|
||||
// Get the animations for exit and entrance.
|
||||
final CurvedAnimation previousExitScaleAnimation = CurvedAnimation(
|
||||
_previousExitScaleAnimation = CurvedAnimation(
|
||||
parent: _previousController,
|
||||
curve: Curves.easeIn,
|
||||
);
|
||||
final Animation<double> previousExitRotationAnimation = Tween<double>(begin: 1.0, end: 1.0).animate(
|
||||
CurvedAnimation(
|
||||
_previousExitRotationCurvedAnimation?.dispose();
|
||||
_previousExitRotationCurvedAnimation = CurvedAnimation(
|
||||
parent: _previousController,
|
||||
curve: Curves.easeIn,
|
||||
),
|
||||
);
|
||||
|
||||
final Animation<double> previousExitRotationAnimation = Tween<double>(begin: 1.0, end: 1.0).animate(
|
||||
_previousExitRotationCurvedAnimation!
|
||||
);
|
||||
|
||||
final CurvedAnimation currentEntranceScaleAnimation = CurvedAnimation(
|
||||
_currentEntranceScaleAnimation?.dispose();
|
||||
_currentEntranceScaleAnimation = CurvedAnimation(
|
||||
parent: widget.currentController,
|
||||
curve: Curves.easeIn,
|
||||
);
|
||||
|
@ -1425,8 +1436,8 @@ class _FloatingActionButtonTransitionState extends State<_FloatingActionButtonTr
|
|||
final Animation<double> moveRotationAnimation = widget.fabMotionAnimator.getRotationAnimation(parent: widget.fabMoveAnimation);
|
||||
|
||||
// Aggregate the animations.
|
||||
_previousScaleAnimation = AnimationMin<double>(moveScaleAnimation, previousExitScaleAnimation);
|
||||
_currentScaleAnimation = AnimationMin<double>(moveScaleAnimation, currentEntranceScaleAnimation);
|
||||
_previousScaleAnimation = AnimationMin<double>(moveScaleAnimation, _previousExitScaleAnimation!);
|
||||
_currentScaleAnimation = AnimationMin<double>(moveScaleAnimation, _currentEntranceScaleAnimation!);
|
||||
_extendedCurrentScaleAnimation = _currentScaleAnimation.drive(CurveTween(curve: const Interval(0.0, 0.1)));
|
||||
|
||||
_previousRotationAnimation = TrainHoppingAnimation(previousExitRotationAnimation, moveRotationAnimation);
|
||||
|
|
|
@ -11,6 +11,7 @@ library;
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import '../impeller_test_helpers.dart';
|
||||
|
||||
|
@ -30,7 +31,11 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets('Color filter - sepia', (WidgetTester tester) async {
|
||||
testWidgets('Color filter - sepia',
|
||||
// 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 {
|
||||
|
||||
const ColorFilter sepia = ColorFilter.matrix(<double>[
|
||||
0.39, 0.769, 0.189, 0, 0, //
|
||||
0.349, 0.686, 0.168, 0, 0, //
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
|
@ -2820,7 +2821,10 @@ void main() {
|
|||
expect(events.length, 2);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Focus traversal does not throw when no focusable is available in a group', (WidgetTester tester) async {
|
||||
testWidgets('Focus traversal does not throw when no focusable is available in a group',
|
||||
// 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 {
|
||||
await tester.pumpWidget(const MaterialApp(home: Scaffold(body: ListTile(title: Text('title')))));
|
||||
final FocusNode? initialFocus = primaryFocus;
|
||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestItem extends StatelessWidget {
|
||||
const TestItem({ super.key, required this.item, this.width, this.height });
|
||||
|
@ -40,7 +41,10 @@ Widget buildFrame({ int? count, double? width, double? height, Axis? scrollDirec
|
|||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('SliverPrototypeExtentList.builder test', (WidgetTester tester) async {
|
||||
testWidgets('SliverPrototypeExtentList.builder test',
|
||||
// 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 {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
|
|
|
@ -10,6 +10,7 @@ library;
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Centered text', (WidgetTester tester) async {
|
||||
|
@ -188,27 +189,32 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets('Text Fade', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: RepaintBoundary(
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 200.0,
|
||||
height: 200.0,
|
||||
color: Colors.green,
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 100.0,
|
||||
color: Colors.blue,
|
||||
child: const Text(
|
||||
'Pp PPp PPPp PPPPp PPPPpp PPPPppp PPPPppppp ',
|
||||
style: TextStyle(color: Colors.black),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.fade,
|
||||
testWidgets(
|
||||
'Text Fade',
|
||||
// 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 {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: RepaintBoundary(
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 200.0,
|
||||
height: 200.0,
|
||||
color: Colors.green,
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 100.0,
|
||||
color: Colors.blue,
|
||||
child: const Text(
|
||||
'Pp PPp PPPp PPPPp PPPPpp PPPPppp PPPPppppp ',
|
||||
style: TextStyle(color: Colors.black),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.fade,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -216,14 +222,14 @@ void main() {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
find.byType(RepaintBoundary).first,
|
||||
matchesGoldenFile('text_golden.Fade.png'),
|
||||
);
|
||||
});
|
||||
await expectLater(
|
||||
find.byType(RepaintBoundary).first,
|
||||
matchesGoldenFile('text_golden.Fade.png'),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Default Strut text', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
|
|
Loading…
Reference in a new issue