Skip to content

Commit 3c80df5

Browse files
authored
Fix NoSplash not being disposed (#138542)
Fix flutter/flutter#136441
1 parent 0135a33 commit 3c80df5

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

packages/flutter/lib/src/material/no_splash.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class _NoSplashFactory extends InteractiveInkFeatureFactory {
2929
controller: controller,
3030
referenceBox: referenceBox,
3131
color: color,
32+
onRemoved: onRemoved,
3233
);
3334
}
3435
}
@@ -64,4 +65,16 @@ class NoSplash extends InteractiveInkFeature {
6465
@override
6566
void paintFeature(Canvas canvas, Matrix4 transform) {
6667
}
68+
69+
@override
70+
void confirm() {
71+
super.confirm();
72+
dispose();
73+
}
74+
75+
@override
76+
void cancel() {
77+
super.cancel();
78+
dispose();
79+
}
6780
}

packages/flutter/test/material/ink_splash_test.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,39 @@ import 'package:flutter/material.dart';
66
import 'package:flutter_test/flutter_test.dart';
77
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
88

9+
class Page extends StatefulWidget {
10+
const Page({
11+
super.key,
12+
required this.title,
13+
required this.onDispose,
14+
});
15+
16+
final String title;
17+
18+
final void Function()? onDispose;
19+
20+
@override
21+
State<Page> createState() => _PageState();
22+
}
23+
24+
class _PageState extends State<Page> {
25+
@override
26+
void dispose() {
27+
widget.onDispose?.call();
28+
super.dispose();
29+
}
30+
31+
@override
32+
Widget build(BuildContext context) {
33+
return Center(
34+
child: FilledButton(
35+
onPressed: () {},
36+
child: Text(widget.title),
37+
),
38+
);
39+
}
40+
}
41+
942
void main() {
1043
// Regression test for https://github.com/flutter/flutter/issues/21506.
1144
testWidgetsWithLeakTracking('InkSplash receives textDirection', (WidgetTester tester) async {
@@ -66,4 +99,35 @@ void main() {
6699
await tester.pumpAndSettle();
67100
}
68101
});
102+
103+
// Regression test for https://github.com/flutter/flutter/issues/136441.
104+
testWidgetsWithLeakTracking('PageView item can dispose when widget with NoSplash.splashFactory is tapped', (WidgetTester tester) async {
105+
final PageController controller = PageController();
106+
final List<int> disposedPageIndexes = <int>[];
107+
await tester.pumpWidget(MaterialApp(
108+
theme: ThemeData(splashFactory: NoSplash.splashFactory),
109+
home: Scaffold(
110+
body: PageView.builder(
111+
controller: controller,
112+
itemBuilder: (BuildContext context, int index) {
113+
return Page(
114+
title: 'Page $index',
115+
onDispose: () {
116+
disposedPageIndexes.add(index);
117+
},
118+
);
119+
},
120+
itemCount: 3,
121+
),
122+
),
123+
));
124+
controller.jumpToPage(1);
125+
await tester.pumpAndSettle();
126+
await tester.tap(find.text('Page 1'));
127+
await tester.pumpAndSettle();
128+
controller.jumpToPage(0);
129+
await tester.pumpAndSettle();
130+
expect(disposedPageIndexes, <int>[0, 1]);
131+
controller.dispose();
132+
});
69133
}

0 commit comments

Comments
 (0)