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

7uhlpewt  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(136)

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

import 'package:flutter_riverpod/flutter_riverpod.dart';

enum MartialArtsMove {
  hand,
  kick,
  grab;
}

class OneSteps extends Notifier<Map<MartialArtsMove, List<num>>> {
  @override
  Map<MartialArtsMove, List<num>> build() =>
      {for (final k in MartialArtsMove.values) k: <num>[]};

  void setMove(MartialArtsMove martialArtsMove, List<num> items) {
    state[martialArtsMove] = items;
    ref.notifyListeners();
  }

  void clearAll() {
    for (final martialArtsMove in MartialArtsMove.values) {
      state[martialArtsMove]!.clear();
    }
    ref.notifyListeners();
  }
}

final oneStepsProvider = StateProvider<OneSteps>((_) => OneSteps());

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

var oneStepState = ref.watch(oneStepsProvider);

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


我也试

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

g0czyy6m

g0czyy6m1#

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

typedef OneStepsState = Map<MartialArtsMove, List<num>>;

class OneSteps extends Notifier<OneStepsState> {
    // Unmodified, cut for brevity
}

final oneStepsProvider =
    NotifierProvider<OneSteps, OneStepsState>(() => OneSteps());

// Example of how to access the state and react to changes
class HandsText extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ref) {
    final oneStepState = ref.watch(oneStepsProvider);
    final len = oneStepState[MartialArtsMove.hand]!.length;

    return Text('Hands $len');
  }
}

// Example of how to call the notifier methods
class ClearOneStepsButton extends ConsumerWidget {
  @override
  Widget build(context, ref) {
    return IconButton(
      onPressed: () {
        ref.read(oneStepsProvider.notifier).clearAll();
      },
      icon: const Icon(Icons.refresh),
    );
  }
}

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

icomxhvb

icomxhvb2#

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

相关问题