I am trying to manage the backstack
in Flutter
like in Android
we manage it from launchMode
(eg. SingleTask,SingleTop , Standard etc..) , For it i have tried the Routes
in flutter, but did not get the success, please check the below code, which i have tried to achieve the backstack
.
Widget makeRoute(
{@required BuildContext context,
@required String routeName,
Object arguments}) {
final Widget child =
_buildRoute(context: context, routeName: routeName, arguments: arguments);
return child;
}
Widget _buildRoute({
@required BuildContext context,
@required String routeName,
Object arguments,
}) {
switch (routeName) {
case '/':
return SplashScreen();
case '/A': //// NAME OF SCREEN IS A
return A();
case '/B': //// NAME OF SCREEN IS B
MyBean docs = arguments as MyBean;
return B(dataToShow: docs);
case '/C': //// NAME OF SCREEN IS C
MyBean docs = arguments as MyBean;
return C(dataToShow: docs);
case '/D': //// NAME OF SCREEN IS D
return D();
}
}
I am jumping the screens from A->B->C->D are as follow,
From A->B , I navigate it like below.
Navigator.of(context).pushNamed('/B');
From B->C , I navigate it like below.
Navigator.of(context).pushNamed('/C', arguments: myList[index]);
And finally, From C->D , I navigate it like below.
Navigator.of(context).pushNamed('/D');
As from the above code, I successfully navigated to the A------>D screens and also carrying data successfully.
But my main concern is that i want to navigate from the D->A or D->B screen using the backstack without opening another screen, So i have tried the below code but it is not working , please check the below code.
From D->A, I have tried like
Navigator.popUntil(context, ModalRoute.withName('/A'));
And even tried in this manner like below.
Navigator.of(context)
.popUntil(ModalRoute.withName("/A"));
I even this way to manage the flow like below
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.popUntil(context, ModalRoute.withName('/A'));
});
But both are not working properly
Please check my main()
class
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: '',
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.grey,
primaryColor: ColorConst.PRIMARY_COLOR,
accentColor: ColorConst.ACCENT_COLOR,
primaryColorBrightness: Brightness.light,
accentColorBrightness: Brightness.light,
),
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (BuildContext context) => makeRoute(
context: context,
routeName: settings.name,
arguments: settings.arguments,
),
maintainState: true,
fullscreenDialog: false,
);
}
)
);
}
And getting the following exception from above code like below.
═ (2) Exception caught by widgets library ═══════════════════════════════════════════════════
'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2330 pos 12: '!_debugLocked': is not true.
The relevant error-causing widget was:
MaterialApp **file:///Users/apple/Documents/BitBucket%20Projects/loyalityapp_android/lib/main.dart:10:7**
════════════════════════════════════════════════════════════════════════════════════════════════════
I have solved the problem by using the MaterialPageRoute
and referred this link to get the solution Click here
From A->B->C->D screen navigation, I have used this approach
From A->B screen
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "B"),
builder: (context) => SCREEN_B(),
),
);
And from B->C, I haved used this along with parameters like below
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "C"),
builder: (context) => SCREEN_C(dataToShow:myList[index]),
),
);
From C->D screen
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "D"),
builder: (context) => SCREEN_D(),
),
);
And main logic is here navigations from D->A or D->B, from below liens of code
Navigator.popUntil(context, ModalRoute.withName("A")); //YOU CAN USE "B" TO NAVIGATE
At the last one more thing which I need to add here is that when I want to perform any action like refresh activity and anything else from screen D->A
Then inside the A screen, we need to use then
method like below
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(
name: "B"),
builder: (context) =>
B(dataToShow: MYLIST[index]),
),
).then((value) {
//// THIS METHOD IS ENVOKE WHEN SCREEN COME FROM D->A OR B->A, YOU CAN PERFROM CAN TASK HERE
});