flutter - Flutter Riverpod小部件调用了两次

标签 flutter dart

我正在尝试学习Flutter和Riverpod,并尝试使用简洁的代码。我只是注意到我的小部件被调用了两次。如何避免进行不必要的操作?
我的项目只是一个导航栏,它会根据我们单击的按钮加载 View
我的导航栏屏幕:

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;
  }

}
我的navigationBarModel:
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
编辑:在我的navigationBarScreen中,我已对此进行了更改:
body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
这样 :
body : useProvider(navigationProvider).buildScreen(_pageModel.pageState),
必须在onPressed,onTap等中使用context.read(),但是我得到的结果是相同的,我的navigationBarScreen被调用了两次...

最佳答案

我无法运行您的代码,因为缺少某些部分,但我最好的猜测是,因为您同时在监视提供程序本身和提供程序状态,所以这就是为什么它被调用两次的原因。

@override
  Widget build(BuildContext context) {

    print('build navigationScreen');
    // Here you are listening to the state
    final _pageModel = useProvider(navigationProvider.state);

    return SafeArea(
      child: Scaffold(
        // Here you are listening to the provider
        body : context.read(navigationProvider).buildScreen(_pageModel.pageState),
建议不要重构StateNotifier,而不是从navigationProvider状态获取pageModel并将其传递回navigationProvider。
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()
  {
    switch (state.pageState)
    {
      case NavigationBarState.HOME:
        return HomeScreen();
        break;
      case NavigationBarState.PROFIL:
        return Text("Page under construction");
        break;
    }
    return null;
  }

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

关于flutter - Flutter Riverpod小部件调用了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64468579/

相关文章:

flutter - 如何在 Flutter 集成测试中等待按钮启用

firebase - 如何从 Dart VM/Dart 集成测试访问 Firebase Firestore?

flutter - 在 flutter 列表上实现 Dismissible 时出现错误

android - 如何从 Android 服务调用 Dart 代码?

flutter - Flutter 中类似 Image Map 的功能?

android - 在 Flutter 中更新 MaterialPageRoute 的状态

android - 当我在 build.gradle 中打开 flutter 项目红线中的 android 文件夹时出现错误任何想法

flutter - 如何拉伸(stretch)图标以填充父级?

flutter - 在父窗口小部件中访问子窗口小部件的变量(带有Dart的Flutter)

android - 未处理的异常 : MissingPluginException(No implementation found for method scanBarcode on channel flutter_barcode_scanner)