简体   繁体   English

"Flutter Riverpod 不调用函数"

[英]Flutter Riverpod does not call function

I'm starting with Flutter and I chose Riverpod to manage my state.我从 Flutter 开始,我选择 Riverpod 来管理我的状态。 I created a StateNotifier that has two functions, one setSelected that chooses the item in the menu and the other getSelected that checks who was selected and changes the colors.我创建了一个具有两个功能的 StateNotifier,一个 setSelected 选择菜单中的项目,另一个 getSelected 检查谁被选中并更改颜色。 The first works on click but the second only works when starting the page.第一个适用于点击,但第二个仅在启动页面时有效。

Below are my classes:以下是我的课程:

1- MenuNotifier 1- MenuNotifier

class MenuNotifier extends StateNotifier<CategoryModel> {
  MenuNotifier() : super(menuItem);

  static CategoryModel menuItem = CategoryModel.allCategories.first;

  void setSelected(CategoryModel item) {
    menuItem = item;
    print(menuItem.id);
  }

  bool getSelected(CategoryModel item) {
    return menuItem.id == item.id ? true : false;
  }
}

2 - MenuCategoryComponent 2 - 菜单类别组件

final menuProvider = StateNotifierProvider<MenuNotifier, CategoryModel>((ref) {
  return MenuNotifier();
});

class MenuCategoryComponent extends ConsumerWidget {
  List<CategoryModel> allCategories = CategoryModel.allCategories;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Container(
      color: uiColor.second,
      child: ListView.builder(
          itemCount: allCategories.length,
          scrollDirection: Axis.horizontal,
          itemBuilder: (BuildContext context, int index) {
            return Consumer(builder: (context, ref, _) {
              final _menuItem = ref.watch(menuProvider.notifier);
              return Container(
                color: ref
                        .read(menuProvider.notifier)
                        .getSelected(allCategories[index])
                    ? uiColor.comp_1
                    : uiColor.second,
                child: TextButton(
                  style: TextButton.styleFrom(
                    padding: EdgeInsets.zero,
                    alignment: Alignment.center,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(20),
                    ),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.all(10),
                    child: Text(allCategories[index].label!,
                        style: uiTextStyle.text1),
                  ),
                  onPressed: () {
                    ref
                        .read(menuProvider.notifier)
                        .setSelected(allCategories[index]);
                  },
                ),
              );
            });
          }),
    );
  }
}

As you can see I have a Container that should change color with a condition that returns a boolean if the selected item is the same as the current one in the ListView.如您所见,我有一个容器,如果所选项目与 ListView 中的当前项目相同,则该容器应使用返回布尔值的条件更改颜色。 And I use read from Riverpod.我使用从 Riverpod 读取。

I think the problem is you are watching the .notifier<\/code> instead of listening to its changes, by the docs:我认为问题在于您正在观看.notifier<\/code>而不是通过文档收听其更改:

Obtains the [StateNotifier] associated with this [StateNotifierProvider], without listening to it.获取与此 [StateNotifierProvider] 关联的 [StateNotifier],而不监听它。

Listening to this provider may cause providers\/widgets to rebuild in the event that the [StateNotifier] it recreated.如果重新创建了 [StateNotifier],侦听此提供程序可能会导致提供程序\/小部件重新构建。

<\/blockquote>

So if you want to listen to changes you should use ref.watch(menuProvider).因此,如果您想收听更改,您应该使用 ref.watch(menuProvider)。 Also as a tip you could use select to filter that value:另外作为提示,您可以使用 select 过滤该值:

 \/\/\/ No reason to be ConsumerWidget because you're using a Consumer inside class MenuCategoryComponent extends StatelessWidget { List<CategoryModel> allCategories = CategoryModel.allCategories; @override Widget build(BuildContext context) { return Container( color: uiColor.second, child: ListView.builder( itemCount: allCategories.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index) { return Consumer(builder: (context, ref, _) { final isSelected = ref.watch(menuProvider.select((v) => v.getSelected(allCategories[index]))); return Container( color: isSelected ? uiColor.comp_1 : uiColor.second, child: TextButton( style: TextButton.styleFrom( padding: EdgeInsets.zero, alignment: Alignment.center, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), child: Padding( padding: const EdgeInsets.all(10), child: Text(allCategories[index].label!, style: uiTextStyle.text1), ), onPressed: () { ref .read(menuProvider.notifier) .setSelected(allCategories[index]); }, ), ); }); } ), ); } }<\/code><\/pre>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM