I have a Flutter app composed of "sub-apps" with different theme colors.
In a sub-app, the AppBar’s back button is working as expected: it navigates back to the previous sub-app page.
However the Android system’s back button is NOT working as expected: it navigates directly to the root app.
The expected back navigation in the following example should be: B3 B2 B1 A3 A2 A1. But it’s B3 A3 A2 A1.
In other words, I want the Android back button to work the same way as the Flutter back button.
The same problem happens with iOS "back swipe" gesture (iosPageTransition = true).
Please try the following code on an Android device or emulator and test with the system’s back button.
Note that I use multiple MaterialApps to apply a color theme to all screens of a sub-app.
Also note that WillPopScope
doesn’t work since it’s not triggered by the system’s back button.
import 'package:flutter/material.dart';
void main() {
runApp(_AppA(_PageA(1)));
}
class _ColoredApp extends StatelessWidget {
final Color color;
final Widget home;
final iosPageTransition = false;
_ColoredApp(this.color, this.home);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.light(primary: color),
pageTransitionsTheme: iosPageTransition
? PageTransitionsTheme(
builders: Map.fromIterable(
TargetPlatform.values,
value: (_) => const CupertinoPageTransitionsBuilder(),
),
)
: null,
),
home: home,
);
}
}
class _AppA extends _ColoredApp {
_AppA(Widget home) : super(Colors.red, home);
}
class _AppB extends _ColoredApp {
_AppB(Widget home) : super(Colors.green, home);
}
class _PageA extends StatelessWidget {
final int number;
const _PageA(this.number);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('A$number')),
body: Center(
child: ElevatedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
if (number > 2) return _AppB(_PageB(1));
return _PageA(number + 1);
}));
},
),
),
);
}
}
class _PageB extends StatelessWidget {
final int number;
const _PageB(this.number);
@override
Widget build(BuildContext context) {
var scaffold = Scaffold(
appBar: AppBar(
leading: number == 1 ? BackButton(onPressed: () => Navigator.of(context, rootNavigator: true).pop()) : null,
title: Text('B$number'),
),
body: Center(
child: ElevatedButton(
child: Text('Next'),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return _PageB(number + 1);
}));
},
),
),
);
return scaffold;
}
}
2
Answers
First of all you can’t set two MaterialApp in single flutter app its wrong way to use it, in your code it initialize 2 times.Just change your theme from the page you want to update,
As Dharini said you cannot use 2 material apps, but if you really want to, then here is the workaround for you
Resolution: Pass the BuildContext and Route from B to A and remove route on back tap of icon or android back key.
Navigator.removeRoute(context, route);
Workaround