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

This commit is contained in:
chunhtai 2021-01-06 10:59:04 -08:00 committed by GitHub
parent 161dde55c9
commit 8f07fccee8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 3 deletions

View File

@ -709,6 +709,8 @@ class _AppBarState extends State<AppBar> {
Scaffold.of(context).openEndDrawer();
}
bool? hadBackButtonWhenRouteWasActive;
@override
Widget build(BuildContext context) {
assert(!widget.primary || debugCheckHasMediaQuery(context));
@ -721,7 +723,11 @@ class _AppBarState extends State<AppBar> {
final bool hasDrawer = scaffold?.hasDrawer ?? 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 double toolbarHeight = widget.toolbarHeight ?? kToolbarHeight;
@ -790,7 +796,7 @@ class _AppBarState extends State<AppBar> {
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
} else {
if (!hasEndDrawer && canPop)
if (!hasEndDrawer && hadBackButtonWhenRouteWasActive!)
leading = useCloseButton ? const CloseButton() : const BackButton();
}
}

View File

@ -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
/// rebuild, and any widgets that used [ModalRoute.of] will be
/// notified.
bool get canPop => !isFirst || willHandlePopInternally;
bool get canPop => isActive && (!isFirst || willHandlePopInternally);
// Internals

View File

@ -1122,6 +1122,97 @@ void main() {
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 {
// This is a regression test for https://github.com/flutter/flutter/issues/58665
final Key key = UniqueKey();