Flutter 持久侧边栏

Flutter persistent sidebar

在我的应用程序中,我希望有一个侧边栏,允许我在我的应用程序的任何地方访问特定功能。


我想要什么:


我是做什么的:

红色是执着sidebar,黄色是我的app content

如果我在 HomeView 中单击我的 profil button,则会显示 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.

任何有关实现此目标的最佳方法的指导将不胜感激。

正如您从 Profil 屏幕截图中看到的那样,边栏不是 Navigator 的小部件子树的一部分(后退按钮仅在配置文件小部件上)。这意味着您无法从侧边栏的 context 中找到 Navigator。发生这种情况是因为您在 MaterialApp 中使用了 builder,其中 inserts widgets above the navigator.

这也是为什么当你想显示启动画面时不能隐藏侧边栏的原因。

您真的需要在 MaterialApp 上使用 builder 吗?然后您可以全局保存导航器并从侧边栏访问它。 This is the first article when I search on DuckDuckGo,你可以关注。

要显示 SplashScreen,您需要向 AppView 添加状态并更改 builder 函数。如果你问我不是很好

我建议您重新考虑您的体系结构并删除 MaterialApp 中的 builder

你可以用一个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 来更改您的 SidebarTemplate。这将处理您在问题中提到的所有要求。

查看实例 here