Unverified Commit 8f07fcce authored by chunhtai's avatar chunhtai Committed by GitHub

app bar leading back button should not change if the route is popped (#71944)

parent 161dde55
...@@ -709,6 +709,8 @@ class _AppBarState extends State<AppBar> { ...@@ -709,6 +709,8 @@ class _AppBarState extends State<AppBar> {
Scaffold.of(context).openEndDrawer(); Scaffold.of(context).openEndDrawer();
} }
bool? hadBackButtonWhenRouteWasActive;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(!widget.primary || debugCheckHasMediaQuery(context)); assert(!widget.primary || debugCheckHasMediaQuery(context));
...@@ -721,7 +723,11 @@ class _AppBarState extends State<AppBar> { ...@@ -721,7 +723,11 @@ class _AppBarState extends State<AppBar> {
final bool hasDrawer = scaffold?.hasDrawer ?? false; final bool hasDrawer = scaffold?.hasDrawer ?? false;
final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false; final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
final bool canPop = parentRoute?.canPop ?? false; hadBackButtonWhenRouteWasActive ??= false;
if (parentRoute?.isActive == true) {
hadBackButtonWhenRouteWasActive = parentRoute!.canPop;
}
assert(hadBackButtonWhenRouteWasActive != null);
final bool useCloseButton = parentRoute is PageRoute<dynamic> && parentRoute.fullscreenDialog; final bool useCloseButton = parentRoute is PageRoute<dynamic> && parentRoute.fullscreenDialog;
final double toolbarHeight = widget.toolbarHeight ?? kToolbarHeight; final double toolbarHeight = widget.toolbarHeight ?? kToolbarHeight;
...@@ -790,7 +796,7 @@ class _AppBarState extends State<AppBar> { ...@@ -790,7 +796,7 @@ class _AppBarState extends State<AppBar> {
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip, tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
); );
} else { } else {
if (!hasEndDrawer && canPop) if (!hasEndDrawer && hadBackButtonWhenRouteWasActive!)
leading = useCloseButton ? const CloseButton() : const BackButton(); leading = useCloseButton ? const CloseButton() : const BackButton();
} }
} }
......
...@@ -1460,7 +1460,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T ...@@ -1460,7 +1460,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// When this changes, if the route is visible, the route will /// When this changes, if the route is visible, the route will
/// rebuild, and any widgets that used [ModalRoute.of] will be /// rebuild, and any widgets that used [ModalRoute.of] will be
/// notified. /// notified.
bool get canPop => !isFirst || willHandlePopInternally; bool get canPop => isActive && (!isFirst || willHandlePopInternally);
// Internals // Internals
......
...@@ -1122,6 +1122,97 @@ void main() { ...@@ -1122,6 +1122,97 @@ void main() {
expect(find.byIcon(Icons.menu), findsNothing); expect(find.byIcon(Icons.menu), findsNothing);
}); });
testWidgets('AppBar does not update the leading if a route is popped case 1', (WidgetTester tester) async {
final Page<void> page1 = MaterialPage<void>(
key: const ValueKey<String>('1'),
child: Scaffold(
key: const ValueKey<String>('1'),
appBar: AppBar(),
)
);
final Page<void> page2 = MaterialPage<void>(
key: const ValueKey<String>('2'),
child: Scaffold(
key: const ValueKey<String>('2'),
appBar: AppBar(),
)
);
List<Page<void>> pages = <Page<void>>[ page1 ];
await tester.pumpWidget(
MaterialApp(
home: Navigator(
pages: pages,
onPopPage: (Route<dynamic> route, dynamic result) => false,
),
),
);
expect(find.byType(BackButton), findsNothing);
// Update pages
pages = <Page<void>>[ page2 ];
await tester.pumpWidget(
MaterialApp(
home: Navigator(
pages: pages,
onPopPage: (Route<dynamic> route, dynamic result) => false,
),
),
);
expect(find.byType(BackButton), findsNothing);
});
testWidgets('AppBar does not update the leading if a route is popped case 2', (WidgetTester tester) async {
final Page<void> page1 = MaterialPage<void>(
key: const ValueKey<String>('1'),
child: Scaffold(
key: const ValueKey<String>('1'),
appBar: AppBar(),
)
);
final Page<void> page2 = MaterialPage<void>(
key: const ValueKey<String>('2'),
child: Scaffold(
key: const ValueKey<String>('2'),
appBar: AppBar(),
)
);
List<Page<void>> pages = <Page<void>>[ page1, page2 ];
await tester.pumpWidget(
MaterialApp(
home: Navigator(
pages: pages,
onPopPage: (Route<dynamic> route, dynamic result) => false,
),
),
);
// The page2 should have a back button
expect(
find.descendant(
of: find.byKey(const ValueKey<String>('2')),
matching: find.byType(BackButton),
),
findsOneWidget
);
// Update pages
pages = <Page<void>>[ page1 ];
await tester.pumpWidget(
MaterialApp(
home: Navigator(
pages: pages,
onPopPage: (Route<dynamic> route, dynamic result) => false,
),
),
);
await tester.pump(const Duration(milliseconds: 10));
// The back button should persist during the pop animation.
expect(
find.descendant(
of: find.byKey(const ValueKey<String>('2')),
matching: find.byType(BackButton),
),
findsOneWidget
);
});
testWidgets('AppBar ink splash draw on the correct canvas', (WidgetTester tester) async { testWidgets('AppBar ink splash draw on the correct canvas', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/58665 // This is a regression test for https://github.com/flutter/flutter/issues/58665
final Key key = UniqueKey(); final Key key = UniqueKey();
......
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