Unverified Commit fab3eb21 authored by xster's avatar xster Committed by GitHub

Let Material BackButton have a custom onPressed handler (#39600)

parent a50eda8f
......@@ -1259,7 +1259,8 @@ class CupertinoNavigationBarBackButton extends StatelessWidget {
/// to pop the [Navigator].
///
/// It can, for instance, be used to pop the platform's navigation stack
/// instead of Flutter's [Navigator].
/// via [SystemNavigator] instead of Flutter's [Navigator] in add-to-app
/// situations.
///
/// Defaults to null.
final VoidCallback onPressed;
......
......@@ -48,7 +48,8 @@ class BackButtonIcon extends StatelessWidget {
///
/// A [BackButton] is an [IconButton] with a "back" icon appropriate for the
/// current [TargetPlatform]. When pressed, the back button calls
/// [Navigator.maybePop] to return to the previous route.
/// [Navigator.maybePop] to return to the previous route unless a custom
/// [onPressed] callback is provided.
///
/// When deciding to display a [BackButton], consider using
/// `ModalRoute.of(context)?.canPop` to check whether the current route can be
......@@ -72,7 +73,7 @@ class BackButtonIcon extends StatelessWidget {
class BackButton extends StatelessWidget {
/// Creates an [IconButton] with the appropriate "back" icon for the current
/// target platform.
const BackButton({ Key key, this.color }) : super(key: key);
const BackButton({ Key key, this.color, this.onPressed }) : super(key: key);
/// The color to use for the icon.
///
......@@ -80,6 +81,16 @@ class BackButton extends StatelessWidget {
/// which usually matches the ambient [Theme]'s [ThemeData.iconTheme].
final Color color;
/// An override callback to perform instead of the default behavior which is
/// to pop the [Navigator].
///
/// It can, for instance, be used to pop the platform's navigation stack
/// via [SytemNavigator] instead of Flutter's [Navigator] in add-to-app
/// situations.
///
/// Defaults to null.
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
......@@ -88,7 +99,11 @@ class BackButton extends StatelessWidget {
color: color,
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () {
Navigator.maybePop(context);
if (onPressed != null) {
onPressed();
} else {
Navigator.maybePop(context);
}
},
);
}
......
......@@ -34,6 +34,37 @@ void main() {
expect(find.text('Home'), findsOneWidget);
});
testWidgets('BackButton onPressed overrides default pop behavior', (WidgetTester tester) async {
bool backPressed = false;
await tester.pumpWidget(
MaterialApp(
home: const Material(child: Text('Home')),
routes: <String, WidgetBuilder>{
'/next': (BuildContext context) {
return Material(
child: Center(
child: BackButton(onPressed: () => backPressed = true),
),
);
},
},
)
);
tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
await tester.pumpAndSettle();
await tester.tap(find.byType(BackButton));
await tester.pumpAndSettle();
// We're still on the second page.
expect(find.text('Home'), findsNothing);
// But the custom callback is called.
expect(backPressed, true);
});
testWidgets('BackButton icon', (WidgetTester tester) async {
final Key iOSKey = UniqueKey();
final Key androidKey = 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