dart 如何获得Riverpod 2状态的长度,这是一个Map?

7uhlpewt  于 2024-01-04  发布在  其他
关注(0)|答案(2)|浏览(220)

我在访问我的Map状态以获取列表MartialArtsMove. hand的长度时遇到问题。
以下是我的类/提供者:

  1. import 'package:flutter_riverpod/flutter_riverpod.dart';
  2. enum MartialArtsMove {
  3. hand,
  4. kick,
  5. grab;
  6. }
  7. class OneSteps extends Notifier<Map<MartialArtsMove, List<num>>> {
  8. @override
  9. Map<MartialArtsMove, List<num>> build() =>
  10. {for (final k in MartialArtsMove.values) k: <num>[]};
  11. void setMove(MartialArtsMove martialArtsMove, List<num> items) {
  12. state[martialArtsMove] = items;
  13. ref.notifyListeners();
  14. }
  15. void clearAll() {
  16. for (final martialArtsMove in MartialArtsMove.values) {
  17. state[martialArtsMove]!.clear();
  18. }
  19. ref.notifyListeners();
  20. }
  21. }
  22. final oneStepsProvider = StateProvider<OneSteps>((_) => OneSteps());

字符串
这是我在我的页面上使用它的方式:

  1. var oneStepState = ref.watch(oneStepsProvider);
  2. Text(
  3. 'Hands ${oneStepState.state[MartialArtsMove.hand]!.length}',
  4. textAlign: TextAlign.center,
  5. // overflow: TextOverflow.ellipsis,
  6. style: const TextStyle(fontSize: 14),
  7. )


我也试

  1. Text(
  2. 'Hands ${oneStepState[MartialArtsMove.hand]!.length}',
  3. textAlign: TextAlign.center,
  4. // overflow: TextOverflow.ellipsis,
  5. style: const TextStyle(fontSize: 14),
  6. )

g0czyy6m

g0czyy6m1#

你创建了一个Notifier,但随后通过StateProvider暴露了它。这些类并不是设计来一起工作的,事实上,你共享的代码包含一个linter警告,警告你不应该从类外部访问Notifier.state。最简单的解决方法是将你的provider类型更改为NotifierProvider,并更新你的ref用法,以分别检索通知程序及其状态:

  1. typedef OneStepsState = Map<MartialArtsMove, List<num>>;
  2. class OneSteps extends Notifier<OneStepsState> {
  3. // Unmodified, cut for brevity
  4. }
  5. final oneStepsProvider =
  6. NotifierProvider<OneSteps, OneStepsState>(() => OneSteps());
  7. // Example of how to access the state and react to changes
  8. class HandsText extends ConsumerWidget {
  9. @override
  10. Widget build(BuildContext context, ref) {
  11. final oneStepState = ref.watch(oneStepsProvider);
  12. final len = oneStepState[MartialArtsMove.hand]!.length;
  13. return Text('Hands $len');
  14. }
  15. }
  16. // Example of how to call the notifier methods
  17. class ClearOneStepsButton extends ConsumerWidget {
  18. @override
  19. Widget build(context, ref) {
  20. return IconButton(
  21. onPressed: () {
  22. ref.read(oneStepsProvider.notifier).clearAll();
  23. },
  24. icon: const Icon(Icons.refresh),
  25. );
  26. }
  27. }

字符串
Here's a working Dartpad演示更改+其他一些杂项重构,例如使状态不可变,这在Riverpod中更惯用。

展开查看全部
icomxhvb

icomxhvb2#

StateProvider是您只想读写值的情况下的正确Provider。
对于类似上面的情况,您可以使用一个NotifierProvider来让一个定义好的操作(方法)更新状态。
你可以在下面阅读更多关于这一点。

相关问题