Flutter Flitter riverpod小部件调用了两次

Flutter Flitter riverpod小部件调用了两次,flutter,dart,riverpod,Flutter,Dart,Riverpod,我正在努力学习颤振和Riverpod,并尝试使用干净的代码。我只是注意到我的小部件被调用了两次。如何避免不必要的操作 我的项目只是一个导航栏,根据我们单击的按钮加载视图 我的导航栏屏幕: class NavigationBarScreen extends HookWidget { @override Widget build(BuildContext context) { print('build navigationScreen'); final _pageMode

我正在努力学习颤振和Riverpod,并尝试使用干净的代码。我只是注意到我的小部件被调用了两次。如何避免不必要的操作

我的项目只是一个导航栏,根据我们单击的按钮加载视图

我的导航栏屏幕:

class NavigationBarScreen extends HookWidget
{

  @override
  Widget build(BuildContext context) {

    print('build navigationScreen');
    final _pageModel = useProvider(navigationProvider.state);

    return SafeArea(
      child: Scaffold(
        body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
        bottomNavigationBar: Container(
              margin: EdgeInsets.only(left : 8, right : 8, bottom: 8),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.only(
                    topRight: Radius.circular(20), topLeft: Radius.circular(20)),
                boxShadow: [
                  BoxShadow(color: AppColors.colorShadowLight, spreadRadius: 0, blurRadius: 10),
                ],
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(50.0),
                child: BottomNavigationBar(
                  type: BottomNavigationBarType.fixed,
                  backgroundColor: AppColors.colorBgDark,
                  fixedColor: AppColors.colorContrastOrange,
                  unselectedItemColor: AppColors.colorFontLight2,
                  currentIndex: _pageModel.navigationIndexItem,
                  showSelectedLabels: false,
                  showUnselectedLabels: false,
                  onTap: context.read(navigationProvider).selectPage,
                  items: [
                    BottomNavigationBarItem(
                      icon: Icon(Icons.home),
                      title: Text('Home'),
                    ),
                    BottomNavigationBarItem(
                      icon: Icon(Icons.settings),
                      title: Text('Settings'),
                    ),
                  ],
                ),
              ),
            ),
      ),
    );
  }

}
enum NavigationBarState
{
  HOME, PROFIL
}

class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
  NavigationNotifier() : super(_initialPage);

  static const int _initialIndex = 0;
  static const NavigationBarState _initialState = NavigationBarState.HOME;
  static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);

  void selectPage(int i)
  {
    switch (i)
    {
      case 0:
        state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
        break;
      case 1:
        state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
        break;
    }
  }

  Widget buildScreen(NavigationBarState page)
  {
    switch (page)
    {
      case NavigationBarState.HOME:
        return HomeScreen();
        break;
      case NavigationBarState.PROFIL:
        return Text("Page under construction");
        break;
    }
    return null;
  }

}
class NavigationBarModel {
  const NavigationBarModel({this.pageState, this.navigationIndexItem});
  final NavigationBarState pageState;
  final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
我的导航通知程序:

class NavigationBarScreen extends HookWidget
{

  @override
  Widget build(BuildContext context) {

    print('build navigationScreen');
    final _pageModel = useProvider(navigationProvider.state);

    return SafeArea(
      child: Scaffold(
        body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
        bottomNavigationBar: Container(
              margin: EdgeInsets.only(left : 8, right : 8, bottom: 8),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.only(
                    topRight: Radius.circular(20), topLeft: Radius.circular(20)),
                boxShadow: [
                  BoxShadow(color: AppColors.colorShadowLight, spreadRadius: 0, blurRadius: 10),
                ],
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(50.0),
                child: BottomNavigationBar(
                  type: BottomNavigationBarType.fixed,
                  backgroundColor: AppColors.colorBgDark,
                  fixedColor: AppColors.colorContrastOrange,
                  unselectedItemColor: AppColors.colorFontLight2,
                  currentIndex: _pageModel.navigationIndexItem,
                  showSelectedLabels: false,
                  showUnselectedLabels: false,
                  onTap: context.read(navigationProvider).selectPage,
                  items: [
                    BottomNavigationBarItem(
                      icon: Icon(Icons.home),
                      title: Text('Home'),
                    ),
                    BottomNavigationBarItem(
                      icon: Icon(Icons.settings),
                      title: Text('Settings'),
                    ),
                  ],
                ),
              ),
            ),
      ),
    );
  }

}
enum NavigationBarState
{
  HOME, PROFIL
}

class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
  NavigationNotifier() : super(_initialPage);

  static const int _initialIndex = 0;
  static const NavigationBarState _initialState = NavigationBarState.HOME;
  static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);

  void selectPage(int i)
  {
    switch (i)
    {
      case 0:
        state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
        break;
      case 1:
        state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
        break;
    }
  }

  Widget buildScreen(NavigationBarState page)
  {
    switch (page)
    {
      case NavigationBarState.HOME:
        return HomeScreen();
        break;
      case NavigationBarState.PROFIL:
        return Text("Page under construction");
        break;
    }
    return null;
  }

}
class NavigationBarModel {
  const NavigationBarModel({this.pageState, this.navigationIndexItem});
  final NavigationBarState pageState;
  final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
在run inspector中,我有以下内容:

class NavigationBarScreen extends HookWidget
{

  @override
  Widget build(BuildContext context) {

    print('build navigationScreen');
    final _pageModel = useProvider(navigationProvider.state);

    return SafeArea(
      child: Scaffold(
        body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
        bottomNavigationBar: Container(
              margin: EdgeInsets.only(left : 8, right : 8, bottom: 8),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.only(
                    topRight: Radius.circular(20), topLeft: Radius.circular(20)),
                boxShadow: [
                  BoxShadow(color: AppColors.colorShadowLight, spreadRadius: 0, blurRadius: 10),
                ],
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(50.0),
                child: BottomNavigationBar(
                  type: BottomNavigationBarType.fixed,
                  backgroundColor: AppColors.colorBgDark,
                  fixedColor: AppColors.colorContrastOrange,
                  unselectedItemColor: AppColors.colorFontLight2,
                  currentIndex: _pageModel.navigationIndexItem,
                  showSelectedLabels: false,
                  showUnselectedLabels: false,
                  onTap: context.read(navigationProvider).selectPage,
                  items: [
                    BottomNavigationBarItem(
                      icon: Icon(Icons.home),
                      title: Text('Home'),
                    ),
                    BottomNavigationBarItem(
                      icon: Icon(Icons.settings),
                      title: Text('Settings'),
                    ),
                  ],
                ),
              ),
            ),
      ),
    );
  }

}
enum NavigationBarState
{
  HOME, PROFIL
}

class NavigationNotifier extends StateNotifier<NavigationBarModel>
{
  NavigationNotifier() : super(_initialPage);

  static const int _initialIndex = 0;
  static const NavigationBarState _initialState = NavigationBarState.HOME;
  static const _initialPage = NavigationBarModel(pageState : _initialState, navigationIndexItem : _initialIndex);

  void selectPage(int i)
  {
    switch (i)
    {
      case 0:
        state = NavigationBarModel(pageState : NavigationBarState.HOME, navigationIndexItem : i);
        break;
      case 1:
        state = NavigationBarModel(pageState : NavigationBarState.PROFIL, navigationIndexItem : i);
        break;
    }
  }

  Widget buildScreen(NavigationBarState page)
  {
    switch (page)
    {
      case NavigationBarState.HOME:
        return HomeScreen();
        break;
      case NavigationBarState.PROFIL:
        return Text("Page under construction");
        break;
    }
    return null;
  }

}
class NavigationBarModel {
  const NavigationBarModel({this.pageState, this.navigationIndexItem});
  final NavigationBarState pageState;
  final int navigationIndexItem;
}
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
I/flutter (32738): build navigationScreen
I/flutter (32738): build homeScreen
编辑:在我的导航栏屏幕中,我更改了以下内容:

body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
据此:

body : useProvider(navigationProvider).buildScreen(_pageModel.pageState),

context.read()必须在onPressed、onTap、。。。但是我得到了相同的结果,我的navigationBarScreen被调用了两次…

我无法运行您的代码,因为缺少部分,但我最好的猜测是,因为您正在查看提供程序本身和提供程序状态,所以它被调用了两次

@覆盖
小部件构建(构建上下文){
打印(“构建导航屏幕”);
//这是你正在收听的国家广播
final _pageModel=useProvider(navigationProvider.state);
返回安全区(
孩子:脚手架(
//这里您正在收听提供商的节目
正文:context.read(navigationProvider).buildScreen(_pageModel.pageState),
我建议重构StateNotifier,而不是从navigationProvider状态获取页面模型并将其传递回navigationProvider

class NavigationNotifier扩展了StateNotifier
{
NavigationNotifier():超级(\u initialPage);
静态常数int _initialIndex=0;
静态常量NavigationBarState _initialState=NavigationBarState.HOME;
静态常量_initialPage=NavigationBarModel(页面状态:_initialState,navigationIndexItem:_initialIndex);
无效选择页(int i)
{
开关(一)
{
案例0:
状态=NavigationBarModel(页面状态:NavigationBarState.HOME,navigationIndexItem:i);
打破
案例1:
状态=NavigationBarModel(页面状态:NavigationBarState.profile,navigationIndexItem:i);
打破
}
}
Widget buildScreen()
{
开关(state.pageState)
{
案例导航BarState.HOME:
返回主屏幕();
打破
案例导航BarState.profile:
返回文本(“正在构建的页面”);
打破
}
返回null;
}
}

然后从构建方法的顶部删除
final\u pageModel=useProvider(navigationProvider.state);

感谢您的回复。