在我的应用程序中,我希望有一个侧边栏,使我可以访问应用程序中各处的特定功能。
我想要什么:
我做什么:
红色是执着的
sidebar
,黄色是我的app content
。
如果我点击
profil button
中的 HomeView
,则会显示 ProfilView
,并且我的侧边栏仍然可见,所以没问题
我的
AppView
:
class AppView extends StatelessWidget {
const AppView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: AppConfig.kAppName,
debugShowCheckedModeBanner: false,
theme: AppTheme().data,
builder: (context, child) => SidebarTemplate(child: child), // => I create a template
onGenerateRoute: RouterClass.generate,
initialRoute: RouterName.kHome,
);
}
我的
SidebarTemplate
:(显示侧边栏并使用我的路由器加载页面)
class SidebarTemplate extends StatelessWidget {
final Widget? child;
const SidebarTemplate({Key? key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body : Row(
children: [
SidebarAtom(), // => My sidebar Widget
Expanded(
child: ClipRect(
child: child! // => My view
),
)
],
)
),
);
}
}
我的
RouterClass
:
abstract class RouterClass{
static Route<dynamic> generate(RouteSettings settings){
final args = settings.arguments;
switch(settings.name){
case RouterName.kHome:
return MaterialPageRoute(
builder: (context) => HomeView()
);
case RouterName.kProfil:
return MaterialPageRoute(
builder: (context) => ProfilView(title: "Profil",)
);
default:
return MaterialPageRoute(
builder: (context) => Error404View(title: "Erreur")
);
}
}
}
如何做:
The following assertion was thrown while handling a gesture:
I/flutter (28519): Navigator operation requested with a context that does not include a Navigator.
I/flutter (28519): The context used to push or pop routes from the Navigator must be that of a widget that is a
I/flutter (28519): descendant of a Navigator widget.
SplashScreen
任何有关实现此目标的最佳方法的指导将不胜感激。
您可以使用
NavigatorObserver
来收听路线的变化。
class MyNavObserver with NavigatorObserver {
final StreamController<int> streamController;
MyNavObserver({required this.streamController});
@override
void didPop(Route route, Route? previousRoute) {
if (previousRoute != null) {
if (previousRoute.settings.name == null) {
streamController.add(3);
} else {
streamController
.add(int.parse(previousRoute.settings.name!.split('/').last));
}
}
}
@override
void didPush(Route route, Route? previousRoute) {
if (route.settings.name == null) {
streamController.add(3);
} else {
streamController.add(int.parse(route.settings.name!.split('/').last));
}
}
}
并使用
StreamController
,您可以通过将其放入 SidebarTemplate
中来对 StreamBuilder
进行更改。这将满足您在问题中提到的所有要求。
查看现场示例此处。
正如您从
Profil
屏幕截图中看到的,侧边栏不是 Navigator
的小部件子树的一部分(后退按钮仅位于配置文件小部件上)。这意味着您无法从侧边栏的 Navigator
中找到 context
。发生这种情况是因为您在 builder
中使用 MaterialApp
在导航器上方插入小部件。
这也是为什么当你想显示闪屏时无法隐藏侧边栏的原因。
您真的需要在
builder
上使用 MaterialApp
吗?然后您可以全局保存导航器并从侧边栏访问它。 这是我在DuckDuckGo搜索的第一篇文章,大家可以关注。
要显示 SplashScreen,您需要向
AppView
添加状态并更改 builder
函数。如果你问我的话,不太好。
我建议你重新思考你的架构,去掉
builder
中的 MaterialApp
。
您可以分享您的 SidebarAtom() 小部件吗?