重建页面时Flutter重建底部导航栏

时间:2020-06-26 16:08:26

标签: flutter dart

当其中一个页面被重建时,如何重建底部导航栏?

例如,我有一个setState调用会重建页面,但不会重建导航栏,因为它用作页面返回的Scaffold中bottomNavigationBar属性的一部分:

    return SafeArea(child: Scaffold(
      bottomNavigationBar: CustomBottomNavigationBar(0),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: buttonCards,
      )
    ));

如何重新构建导航栏?

编辑:这是我的CustomBottomNavigationBar实现供参考:

class CustomBottomNavigationBar extends StatefulWidget {
  
  int _currentIndex = 0;
  
  CustomBottomNavigationBar(this._currentIndex);
  
  @override
  CustomBottomNavigationBarState createState() => CustomBottomNavigationBarState(_currentIndex);

}

class CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> with TickerProviderStateMixin {
  
  int _currentIndex = 0;
  List<_NavigationIconView> _navigationViews;
  
  CustomBottomNavigationBarState(this._currentIndex); 

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_navigationViews == null) {
      _navigationViews = <_NavigationIconView>[
        _NavigationIconView(
          icon: Icon(Icons.home),
          title: "Home",
          route: HomePage.route,
          vsync: this,
        ) ,
        _NavigationIconView(
          icon: const Icon(Icons.casino),
          title: "Game",
          route: GameStartPage.route,
          vsync: this,
        ),
        _NavigationIconView(
          icon: const Icon(Icons.settings),
          title: "Settings",
          route: SettingsPage.route,
          vsync: this,
        ),
      ];
      
      _navigationViews[_currentIndex].controller.value = 1;
    }
  }
  
  BottomNavigationBar build(BuildContext context) {
    
    var bottomNavigationBarItems = _navigationViews
      .map<BottomNavigationBarItem>((navigationView) => navigationView.item)
      .toList();
    
    return BottomNavigationBar(
      showUnselectedLabels: false,
      items: bottomNavigationBarItems,
      currentIndex: _currentIndex,
      type: BottomNavigationBarType.fixed,
      onTap: (index) {
        setState(() {
          _navigationViews[_currentIndex].controller.reverse();
          _currentIndex = index;
          _navigationViews[_currentIndex].controller.forward();
          Navigator.pushNamed(context, _navigationViews[_currentIndex].route);
        });
      },
      selectedItemColor: Theme
        .of(context)
        .colorScheme
        .primaryLight,
      unselectedItemColor: Theme
        .of(context)
        .colorScheme
        .primaryLight
        .withOpacity(0.38),
    );
  }
  
  @override
  void dispose() {
    for (final view in _navigationViews) {
      view.controller.dispose();
    }
    super.dispose();
  }
}

class _NavigationIconView {
  _NavigationIconView({
    this.title,
    this.icon,
    this.route,
    TickerProvider vsync,
  }) : item = BottomNavigationBarItem(
    icon: icon,
    title: Text(title),
  ),
    controller = AnimationController(
      duration: kThemeAnimationDuration,
      vsync: vsync,
    );
  
  final String title;
  final Widget icon;
  final String route;
  final BottomNavigationBarItem item;
  final AnimationController controller;
}

1 个答案:

答案 0 :(得分:1)

您将需要在CustomBottomNavigationBar上调用set状态,因为它具有自己的生成方法。这实际上是一件好事,因为它不是在每次重新构建父小部件时都构建的。

我在stackoverflow上找到了一个答案,可以用来调用setstate here

通常,我建议使用BLOC模式或“范围模型”模式,以便将viewmodel用于任何逻辑。当以这种方式进行操作时,我通常使用消息总线(使用flutter库event_bus)将事件发送到其他订阅该事件的视图模型,并且可能需要更新其视图并调用setState的形式。如果需要,我也可以提供一个示例。