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
late _StandardBottomSheet bottomSheet;
bool removedEntry = false;
bool doingDispose = false;
void _removeCurrentBottomSheet() {
removedEntry = true;
if (_currentBottomSheet == null) {
......@@ -2380,11 +2381,19 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
final LocalHistoryEntry? entry = isPersistent
? null
: LocalHistoryEntry(onRemove: () {
if (!removedEntry && _currentBottomSheet?._widget == bottomSheet) {
if (!removedEntry && _currentBottomSheet?._widget == bottomSheet && !doingDispose) {
_removeCurrentBottomSheet();
}
});
void _removeEntryIfNeeded() {
if (!isPersistent && !removedEntry) {
assert(entry != null);
entry!.remove();
removedEntry = true;
}
}
bottomSheet = _StandardBottomSheet(
key: bottomSheetKey,
animationController: animationController,
......@@ -2394,11 +2403,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
return;
}
assert(_currentBottomSheet!._widget == bottomSheet);
if (!isPersistent && !removedEntry) {
assert(entry != null);
entry!.remove();
removedEntry = true;
}
_removeEntryIfNeeded();
},
onDismissed: () {
if (_dismissedBottomSheets.contains(bottomSheet)) {
......@@ -2408,6 +2413,8 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
}
},
onDispose: () {
doingDispose = true;
_removeEntryIfNeeded();
if (shouldDisposeAnimationController) {
animationController.dispose();
}
......
......@@ -1149,6 +1149,50 @@ void main() {
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
testWidgets('The framework does not dispose of the transitionAnimationController provided by user.', (WidgetTester tester) async {
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