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

Flutter 重建页面时颤振重建底部导航栏,flutter,dart,Flutter,Dart,当重建其中一个页面时,如何重建底部导航栏 例如,我有一个重建页面的setState调用,但它不重建导航栏,因为它是从页面返回的Scaffold中bottomNavigationBar属性的一部分: return SafeArea(child: Scaffold( bottomNavigationBar: CustomBottomNavigationBar(0), body: Column( mainAxisAlignment: MainAxisAl

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

例如,我有一个重建页面的
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;
}
类CustomBottomNavigationBar扩展StatefulWidget{
int _currentIndex=0;
CustomBottomNavigationBar(此.\u当前索引);
@凌驾
CustomBottomNavigationBarState createState()=>CustomBottomNavigationBarState(_currentIndex);
}
类CustomBottomNavigationBarState使用TickerProviderStateMixin扩展状态{
int _currentIndex=0;
列表导航视图;
CustomBottomNavigationBarState(此._currentIndex);
@凌驾
void didChangeDependencies(){
super.didChangeDependencies();
如果(_navigationViews==null){
_导航视图=[
_导航图标视图(
图标:图标(Icons.home),
标题:“家”,
路线:HomePage.route,
vsync:这个,,
) ,
_导航图标视图(
图标:const图标(Icons.casino),
标题:“游戏”,
路线:GameStartPage.route,
vsync:这个,,
),
_导航图标视图(
图标:常量图标(图标.设置),
标题:“设置”,
路线:设置SPAGE.route,
vsync:这个,,
),
];
_navigationViews[\u currentIndex].controller.value=1;
}
}
BottomNavigationBar构建(构建上下文){
var bottomNavigationBarItems=\u navigationViews
.map((navigationView)=>navigationView.item)
.toList();
返回底部导航栏(
显示未选择的标签:false,
项目:bottomNavigationBarItems,
currentIndex:_currentIndex,
类型:BottomNavigationBarType.fixed,
onTap:(索引){
设置状态(){
_导航视图[_currentIndex].controller.reverse();
_currentIndex=索引;
_导航视图[_currentIndex].controller.forward();
Navigator.pushNamed(上下文,_navigationViews[_currentIndex].route);
});
},
selectedItemColor:主题
.of(上下文)
.配色方案
primaryLight先生,
unselectedItemColor:主题
.of(上下文)
.配色方案
primaryLight先生
.不透明度(0.38),
);
}
@凌驾
无效处置(){
用于(导航视图中的最终视图){
view.controller.dispose();
}
super.dispose();
}
}
类导航图标视图{
_导航图标视图({
这个名字,
这个图标,
这条路线,,
TickerProvider vsync,
}):item=BottomNavigationBarItem(
图标:图标,
标题:文本(标题),
),
控制器=动画控制器(
持续时间:kThemeAnimationDuration,
vsync:vsync,
);
最后的字符串标题;
最终小部件图标;
最终管柱路线;
最终底部导航气压项目;
最终动画控制器;
}

您需要在CustomBottomNavigationBar上调用set state,因为它有自己的构建方法。这实际上是一件好事,因为它不是在每次父窗口小部件进行重建时构建的

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


通常,我建议使用集团模式或范围模型模式,以便对任何逻辑使用viewmodels。这样做时,我通常使用消息总线(我使用颤振库事件_总线)将事件发送到订阅该事件的其他视图模型,并且可能需要更新其视图并调用setState形式。如果需要,我也可以提供一个例子。

您的custombottombar是否有自己的小部件和自己的构建方法?@rlefler:是的,有自己的构建方法。添加导航栏类实现示例的详细信息将非常有用。