【问题标题】:Flutter auto_route | Pass data to outer router in nested navigation颤振自动路由 |在嵌套导航中将数据传递给外部路由器
【发布时间】:2022-12-11 05:15:42
【问题描述】:

我正在使用颤振自动路由对于我的嵌套导航,我想将数据(AppBar-title 的动态字符串和 floatingActionButton 的 Widget)从嵌套路由传递到外部路由(根据路由向上两层)树)。

导航(树)具有以下结构:

@MaterialAutoRouter(
  routes: <AutoRoute>[
    AutoRoute(
      page: MainNavigationView,
      children: [
        AutoRoute(
          path: 'manage',
          page: EmptyRouterPage,
          name: 'ManageRouter',
          children: [
            AutoRoute(
              path: 'object',
              page: ObjectView,
              initial: true,
            ),
            AutoRoute(
              path: 'detail',
              page: ObjectDetailView,
            ),
          ]
        )
      ]
    )
  ]
)

我的页面使用嵌套导航,其中 MainNavigationView 代表 Scaffold,其中包含 AppBarSpeedDial 作为 ScaffoldfloatingActionButton

class MainNavigationView extends StatefulWidget {
...
}

class _MainNavigationViewState extends State<MainNavigationView> {
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {

    return AutoTabsRouter(
      routes: [
        const ManageRouter(),
        ...
      ],
      builder: (context, child, __) {
        final tabsRouter = AutoTabsRouter.of(context);
        return Scaffold(
          key: _scaffoldkey,
          appBar: AppBar(...), //Title needs to be set dynamically
          body: child,
          floatingActionButton: SpeedDial(
            ... //This needs to be set dynamically
          ),
          ...
        );
      },
    );
  }
  ...
}

在路由ManageRouter 内,我可以从ObjectView 导航到ObjectDetailView。从这两个视图来看,我需要为 AppBar 传递一个动态字符串,为 floatingActionButton 传递必要的对象。

我想出的唯一解决方案是 ProviderMainNavigationView 允许我以解耦的方式发送数据。但这似乎有点矫枉过正,对于这种一般的东西。

更新:

我研究了其他几种解决方案。他们都没有在父级中有脚手架并且嵌套路由器将值传递给父级 Scaffold 的场景。我在其他路由器包的其他示例(例如go_router)中看到的是MainNavigationView中的Scaffold,带有bottomNavigationBar属性集,没有appBarfloatingBottons属性集。嵌套内容(Object/ObjectDetail通过ManageRouter)有自己的Scaffold,属性设置为appBarbottomNavigationBar

我已经尝试使用状态管理解决方案解决它,例如 Provider 但除了在构建时触发 notifyListeners() 操作的问题(因为我将 notifyListeners() 操作放在嵌套内容的构建方法中)我有一个关于堆栈管理的问题。处理该逻辑,加上 bottomNavigationBar 的副作用,它有自己的堆栈,我认为这是一个架构问题。

我仍然感谢大家的努力和兴趣!

【问题讨论】:

  • 您只是想将数据从一页传递到另一页吗?您可以使用 getx,它有一个参数选项来传递数据。

标签: flutter nested navigation state-management


【解决方案1】:

我认为 AutoRouter 包没有任何在嵌套路由之间传递参数的功能。你的情况可以更容易解决!

AutoTabs路由器具有名为 activeIndex 的字段。 当您从 MainNavigationView 子项中选择一个页面时,此字段将在 AutoTabsRouter 构建器方法中更新。

我在我的应用程序中使用它在 bottomNavigationBar 中显示选定的页面图标并在 appBar 中显示选定的页面标题。

针对您的情况的解决方案:

class MainNavigationView extends StatefulWidget {
...
}

class _MainNavigationViewState extends State<MainNavigationView> {
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {

    return AutoTabsRouter(
      routes: [
        const ManageRouter(),
        ...
      ],
      builder: (context, child, __) {
        final tabsRouter = AutoTabsRouter.of(context);
        return Scaffold(
          key: _scaffoldkey,
          appBar: AppBar(
            title: tabsRouter.activeIndex == 1? 'ObjectViewTitle' : 'ObjectDetailViewTitle'
          ), //Title needs to be set dynamically
          body: child,
          floatingActionButton: SpeedDial(
            child: tabsRouter.activeIndex == 1? ObjectViewFab() : ObjectDetailViewFab() 
          ),
          ...
        );
      },
    );
  }
  ...
}

【讨论】:

  • 您的解决方案的问题是,标题和 floatingActionButton-object 是静态的。但是在我选择了一个对象之前,我不知道ObjectDetail 会有哪个标题。因此,AppBar-title 和 floatingActionButton 中的数据需要位于特定的ObjectDetail-对象的上下文中。
  • 在这种情况下,请使用 Provider / Bloc / Controller 或其他状态机......在您的情况下,这不是一个糟糕的解决方案。
猜你喜欢
  • 2018-06-14
  • 2019-12-16
  • 2022-11-25
  • 2022-01-11
  • 2017-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多