Unverified Commit 16dda865 authored by xubaolin's avatar xubaolin Committed by GitHub

Fix a ModalbottomSheet bug (#99970)

parent 32c021bd
...@@ -2357,6 +2357,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2357,6 +2357,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
late _StandardBottomSheet bottomSheet; late _StandardBottomSheet bottomSheet;
bool removedEntry = false; bool removedEntry = false;
bool doingDispose = false;
void _removeCurrentBottomSheet() { void _removeCurrentBottomSheet() {
removedEntry = true; removedEntry = true;
if (_currentBottomSheet == null) { if (_currentBottomSheet == null) {
...@@ -2380,11 +2381,19 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2380,11 +2381,19 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
final LocalHistoryEntry? entry = isPersistent final LocalHistoryEntry? entry = isPersistent
? null ? null
: LocalHistoryEntry(onRemove: () { : LocalHistoryEntry(onRemove: () {
if (!removedEntry && _currentBottomSheet?._widget == bottomSheet) { if (!removedEntry && _currentBottomSheet?._widget == bottomSheet && !doingDispose) {
_removeCurrentBottomSheet(); _removeCurrentBottomSheet();
} }
}); });
void _removeEntryIfNeeded() {
if (!isPersistent && !removedEntry) {
assert(entry != null);
entry!.remove();
removedEntry = true;
}
}
bottomSheet = _StandardBottomSheet( bottomSheet = _StandardBottomSheet(
key: bottomSheetKey, key: bottomSheetKey,
animationController: animationController, animationController: animationController,
...@@ -2394,11 +2403,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2394,11 +2403,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
return; return;
} }
assert(_currentBottomSheet!._widget == bottomSheet); assert(_currentBottomSheet!._widget == bottomSheet);
if (!isPersistent && !removedEntry) { _removeEntryIfNeeded();
assert(entry != null);
entry!.remove();
removedEntry = true;
}
}, },
onDismissed: () { onDismissed: () {
if (_dismissedBottomSheets.contains(bottomSheet)) { if (_dismissedBottomSheets.contains(bottomSheet)) {
...@@ -2408,6 +2413,8 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2408,6 +2413,8 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
} }
}, },
onDispose: () { onDispose: () {
doingDispose = true;
_removeEntryIfNeeded();
if (shouldDisposeAnimationController) { if (shouldDisposeAnimationController) {
animationController.dispose(); animationController.dispose();
} }
......
...@@ -1149,6 +1149,50 @@ void main() { ...@@ -1149,6 +1149,50 @@ void main() {
expect(tester.takeException(), isNull); expect(tester.takeException(), isNull);
}); });
// Regression test for https://github.com/flutter/flutter/issues/99627
testWidgets('The old route entry should be removed when a new sheet popup', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
PersistentBottomSheetController<void>? sheetController;
await tester.pumpWidget(MaterialApp(
home: Scaffold(
key: scaffoldKey,
body: const Center(child: Text('body')),
),
));
final ModalRoute<dynamic> route = ModalRoute.of(scaffoldKey.currentContext!)!;
expect(route.canPop, false);
scaffoldKey.currentState!.showBottomSheet<void>((_) {
return Builder(
builder: (BuildContext context) {
return Container(height: 200.0);
},
);
});
await tester.pump();
expect(find.byType(BottomSheet), findsOneWidget);
expect(route.canPop, true);
// Trigger the second sheet will remove the first sheet from tree.
sheetController = scaffoldKey.currentState!.showBottomSheet<void>((_) {
return Builder(
builder: (BuildContext context) {
return Container(height: 200.0);
},
);
});
await tester.pump();
expect(find.byType(BottomSheet), findsOneWidget);
expect(route.canPop, true);
sheetController.close();
expect(route.canPop, false);
});
// Regression test for https://github.com/flutter/flutter/issues/87708 // Regression test for https://github.com/flutter/flutter/issues/87708
testWidgets('The framework does not dispose of the transitionAnimationController provided by user.', (WidgetTester tester) async { testWidgets('The framework does not dispose of the transitionAnimationController provided by user.', (WidgetTester tester) async {
const Key tapTarget = Key('tap-target'); const Key tapTarget = Key('tap-target');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment