Unverified Commit a5a07a78 authored by chunhtai's avatar chunhtai Committed by GitHub

fix overlay entry remove to remove itself from the overlay first if i… (#65126)

parent 87617e4c
......@@ -123,23 +123,26 @@ class OverlayEntry {
///
/// This should only be called once.
///
/// If this method is called while the [SchedulerBinding.schedulerPhase] is
/// [SchedulerPhase.persistentCallbacks], i.e. during the build, layout, or
/// paint phases (see [WidgetsBinding.drawFrame]), then the removal is
/// delayed until the post-frame callbacks phase. Otherwise the removal is
/// done synchronously. This means that it is safe to call during builds, but
/// also that if you do call this during a build, the UI will not update until
/// the next frame (i.e. many milliseconds later).
/// This method removes this overlay entry from the overlay immediately. The
/// UI will be updated in the same frame if this method is called before the
/// overlay rebuild in this frame; otherwise, the UI will be updated in the
/// next frame. This means that it is safe to call during builds, but also
/// that if you do call this after the overlay rebuild, the UI will not update
/// until the next frame (i.e. many milliseconds later).
void remove() {
assert(_overlay != null);
final OverlayState overlay = _overlay;
_overlay = null;
if (!overlay.mounted)
return;
overlay._entries.remove(this);
if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
overlay._remove(this);
overlay._markDirty();
});
} else {
overlay._remove(this);
overlay._markDirty();
}
}
......@@ -405,11 +408,9 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
});
}
void _remove(OverlayEntry entry) {
void _markDirty() {
if (mounted) {
setState(() {
_entries.remove(entry);
});
setState(() {});
}
}
......
......@@ -521,6 +521,57 @@ void main() {
await tester.pumpAndSettle();
});
testWidgets('Pages update does update overlay correctly', (WidgetTester tester) async {
// Regression Test for https://github.com/flutter/flutter/issues/64941.
List<Page<void>> pages = <Page<void>>[
MaterialPage<void>(
key: const ValueKey<int>(0),
builder: (BuildContext context) => const Text('page 0'),
),
MaterialPage<void>(
key: const ValueKey<int>(1),
builder: (BuildContext context) => const Text('page 1'),
),
];
Widget buildNavigator() {
return Navigator(
pages: pages,
onPopPage: (Route<dynamic> route, dynamic result) => false,
);
}
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: buildNavigator(),
),
);
expect(find.text('page 1'), findsOneWidget);
expect(find.text('page 0'), findsNothing);
// Removes the first page.
pages = <Page<void>>[
MaterialPage<void>(
key: const ValueKey<int>(1),
builder: (BuildContext context) => const Text('page 1'),
),
];
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: buildNavigator(),
),
);
// Overlay updates correctly.
expect(find.text('page 1'), findsOneWidget);
expect(find.text('page 0'), findsNothing);
await tester.pumpAndSettle();
expect(find.text('page 1'), findsOneWidget);
expect(find.text('page 0'), findsNothing);
});
testWidgets('replaceNamed replaces', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushReplacementNamed(context, '/A'); }),
......
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