Flutter :- 如何像 Android "SingleTask" 那样管理后台堆栈?
Flutter :- How manage the backstack like in Android "SingleTask"?
我正在尝试管理 Flutter
中的 backstack
,就像在 Android
中一样,我们从 launchMode
(eg. SingleTask,SingleTop, Standard etc..) ,为此我在 flutter 中尝试了 Routes
,但没有成功,请检查下面的代码,我已尝试实现 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();
}
}
我从A->B->C->D跳屏如下,
从 A->B ,我按如下方式导航。
Navigator.of(context).pushNamed('/B');
从 B->C 开始,我按如下方式导航。
Navigator.of(context).pushNamed('/C', arguments: myList[index]);
最后,从 C->D 开始,我按如下方式导航。
Navigator.of(context).pushNamed('/D');
从上面的代码,我成功导航到A------>D屏幕,也成功携带数据。
但我主要担心的是我想在不打开另一个屏幕的情况下使用后台从 D->A 或 D->B 屏幕导航,所以我尝试了下面的代码但是 它不工作,请检查下面的代码。
从D->A,我试过像
Navigator.popUntil(context, ModalRoute.withName('/A'));
甚至像下面这样尝试过。
Navigator.of(context)
.popUntil(ModalRoute.withName("/A"));
我什至像下面这样管理流程
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.popUntil(context, ModalRoute.withName('/A'));
});
但两者都无法正常工作
请检查我的 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,
);
}
)
);
}
并从上面的代码中获取以下异常。
═ (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**
════════════════════════════════════════════════════════════════════════════════════════════════════
如果您使用以下代码使用 Navigator.popUntil 方法弹出直到路由“/A”,那么您应该在 [=28= 的帮助下设置您的开始屏幕] 属性 在您的 MaterialApp 小部件中 而不是 "home" 属性。
Navigator.popUntil(context, ModalRoute.withName('/A'));
Because, here you are navigating to the route "A" with the help of "push navigator routes" and want to pop using "named routes"
此外,您可以在您的路线中使用“/”路线设置它属性作为Follow,
initialRoute : "A",
或
routes:{
"/": (context)=> A(),
}
您的代码中的其他一切都很好。
我已经使用 MaterialPageRoute
解决了这个问题,并引用了这个 link 来获得解决方案
从A->B->C->D画面导航,我都用过这种做法
从A->B屏幕
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "B"),
builder: (context) => SCREEN_B(),
),
);
从 B->C,我使用了它以及如下参数
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "C"),
builder: (context) => SCREEN_C(dataToShow:myList[index]),
),
);
从 C->D 屏幕
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "D"),
builder: (context) => SCREEN_D(),
),
);
这里的主要逻辑是从 D->A 或 D->B 的导航,从下面的代码留置权
Navigator.popUntil(context, ModalRoute.withName("A")); //YOU CAN USE "B" TO NAVIGATE
最后一件事我需要在此处添加的是,当我想执行任何操作(如刷新 activity 以及屏幕 D->A 中的任何其他操作时
然后在A屏里面,我们需要使用下面的then
方法
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
});
我正在尝试管理 Flutter
中的 backstack
,就像在 Android
中一样,我们从 launchMode
(eg. SingleTask,SingleTop, Standard etc..) ,为此我在 flutter 中尝试了 Routes
,但没有成功,请检查下面的代码,我已尝试实现 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();
}
}
我从A->B->C->D跳屏如下,
从 A->B ,我按如下方式导航。
Navigator.of(context).pushNamed('/B');
从 B->C 开始,我按如下方式导航。
Navigator.of(context).pushNamed('/C', arguments: myList[index]);
最后,从 C->D 开始,我按如下方式导航。
Navigator.of(context).pushNamed('/D');
从上面的代码,我成功导航到A------>D屏幕,也成功携带数据。
但我主要担心的是我想在不打开另一个屏幕的情况下使用后台从 D->A 或 D->B 屏幕导航,所以我尝试了下面的代码但是 它不工作,请检查下面的代码。
从D->A,我试过像
Navigator.popUntil(context, ModalRoute.withName('/A'));
甚至像下面这样尝试过。
Navigator.of(context)
.popUntil(ModalRoute.withName("/A"));
我什至像下面这样管理流程
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.popUntil(context, ModalRoute.withName('/A'));
});
但两者都无法正常工作
请检查我的 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,
);
}
)
);
}
并从上面的代码中获取以下异常。
═ (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**
════════════════════════════════════════════════════════════════════════════════════════════════════
如果您使用以下代码使用 Navigator.popUntil 方法弹出直到路由“/A”,那么您应该在 [=28= 的帮助下设置您的开始屏幕] 属性 在您的 MaterialApp 小部件中 而不是 "home" 属性。
Navigator.popUntil(context, ModalRoute.withName('/A'));
Because, here you are navigating to the route "A" with the help of "push navigator routes" and want to pop using "named routes"
此外,您可以在您的路线中使用“/”路线设置它属性作为Follow,
initialRoute : "A",
或
routes:{
"/": (context)=> A(),
}
您的代码中的其他一切都很好。
我已经使用 MaterialPageRoute
解决了这个问题,并引用了这个 link 来获得解决方案
从A->B->C->D画面导航,我都用过这种做法
从A->B屏幕
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "B"),
builder: (context) => SCREEN_B(),
),
);
从 B->C,我使用了它以及如下参数
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "C"),
builder: (context) => SCREEN_C(dataToShow:myList[index]),
),
);
从 C->D 屏幕
Navigator.push(
context,
MaterialPageRoute(
settings: RouteSettings(name: "D"),
builder: (context) => SCREEN_D(),
),
);
这里的主要逻辑是从 D->A 或 D->B 的导航,从下面的代码留置权
Navigator.popUntil(context, ModalRoute.withName("A")); //YOU CAN USE "B" TO NAVIGATE
最后一件事我需要在此处添加的是,当我想执行任何操作(如刷新 activity 以及屏幕 D->A 中的任何其他操作时
然后在A屏里面,我们需要使用下面的then
方法
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
});