在 NavigationRail 中调用我自己的函数后如何更新 selectedIndex?

How to update the selectedIndex after calling my own function inside the NavigationRail?

我这几天一直在开发 Flutter 应用程序。

我已经为我的应用实现了 NavigationRail。它工作得很好,除了一件事。

当我点击 NavigationRailDestination 时,它会调用函数 updateRoute(index) 并转到所需的路线。

我的问题是,selectedIndex 属性 更新了,但是当加载新路由时,selectedIndex 又回到了 0。

这是我的代码:

class SidebarDrawer extends StatefulWidget {

  final VoidCallback callbackOnScreenChange;

  SidebarDrawer({@required this.callbackOnScreenChange});

  @override
  _SidebarDrawerState createState() => _SidebarDrawerState();
}

class _SidebarDrawerState extends State<SidebarDrawer> {

  int index = 0;
  
  @override
  Widget build(BuildContext context) => NavigationRail(
        extended: isExtended,
        onDestinationSelected: (index) => updateRoute(index),
        selectedIndex: index,
        leading: IconButton(
          icon: Icon(Icons.reorder),
          onPressed: () => setState(() => isExtended = !isExtended),
        ),
        destinations: <NavigationRailDestination>[
          <Some NavigationRailDestination>
        ],
      );

  void updateRoute(index) {
  
    setState(() => this.index = index);
    
    switch (index) {
      case 0:
        return navigateToScreen(
            context, '/home', widget.callbackOnScreenChange);
      case 1:
        return navigateToScreen(
            context, '/orderManager', widget.callbackOnScreenChange);
      case 2:
        return navigateToScreen(
            context, '/manualControl', widget.callbackOnScreenChange);
      default:
        return navigateToScreen(
            context, '/home', widget.callbackOnScreenChange);
    }
  }
  
  

函数 navigateToScreen() :

/// Navigate to given widget
void navigateToScreen(BuildContext context, String route,
    VoidCallback callbackOnScreenChange) async {
  // Call callback on screen change
  if (callbackOnScreenChange != null) {
    callbackOnScreenChange();
  }

  // Check the current route
  String currentRoute = ModalRoute.of(context).settings.name;

  // If the current route is not the same as the new route change the screen
  if (currentRoute != route) {
    await Navigator.pushNamed(context, route);
  }
}

我是 Flutter 的新手,我有点难以理解状态是如何工作和更新的。

如果你能帮助我理解它,我将不胜感激!

好的,我已经改正了。

在我的父窗口小部件 (MainScaffold) 中,我将索引值传递给我的子窗口小部件(包含 NavigationRail)。

然后在我的 NavigationRail 小部件中,而不是 属性 : selectedIndex: index 我设置为 selectedIndex: widget.selectedDrawerIndex.

然后在每个屏幕上,当我渲染主脚手架时,我设置了所需的 selectedDrawerIndex 值。

这是 sidebar 小部件的代码:

class SidebarDrawer extends StatefulWidget {
  // Index is used to know which icon is selected
  final int selectedDrawerIndex;
  final VoidCallback callbackOnScreenChange;

  SidebarDrawer({@required this.selectedDrawerIndex, @required this.callbackOnScreenChange});

  @override
  _SidebarDrawerState createState() => _SidebarDrawerState();
}

class _SidebarDrawerState extends State<SidebarDrawer> {

  @override
  Widget build(BuildContext context) => NavigationRail(
        selectedIndex: widget.selectedDrawerIndex,
        leading: IconButton(
          icon: Icon(Icons.reorder),
          onPressed: () => setState(() => isExtended = !isExtended),
        ),
        // When a destination is selected, the routes are updated
        onDestinationSelected: (selectedDrawerIndex) => updateRoute(selectedDrawerIndex),
        destinations: <NavigationRailDestination>[
          [...some navigation rail destinations...]
        ],
      );

  void updateRoute(selectedDrawerIndex) {
    // Navigate to a specific screen when a destination is clicked
    switch (selectedDrawerIndex) {
      case 0:
        return navigateToScreen(
            context, '/home', widget.callbackOnScreenChange);
      case 1:
        return navigateToScreen(
            context, '/orderManager', widget.callbackOnScreenChange);
      case 2:
        return navigateToScreen(
            context, '/manualControl', 
      default:
        return navigateToScreen(
            context, '/home', widget.callbackOnScreenChange);
    }
  }
}

然后在主脚手架中:

class MainScaffold extends StatelessWidget {
  final int selectedDrawerIndex;
  final Widget body;
  // Callback when a screen change is requested
  // This is the current way to make sure a screen calls its dispose method when the screen changes
  final VoidCallback callbackOnScreenChange;

  MainScaffold(
      {@required this.selectedDrawerIndex,
      @required this.body,
      this.callbackOnScreenChange});
      
  [...some more code...]
}

然后我只需要在使用 MainScaffold Widget 时将 selectedDrawerIndex 作为参数传递。

效果很好,但我愿意改进,所以如果您想到更好的解决方案,请不要犹豫 post 它。