【问题标题】:Flutter Riverpod v1.0 - state not updating with StateNotifier ListFlutter Riverpod v1.0 - 状态未使用 StateNotifier 列表更新
【发布时间】:2021-11-27 04:40:27
【问题描述】:

我从 RiverPod 0.4x 迁移到 1.0 stable,现在这个 StateNotifier 不再更新状态,即使动画结束时正在调用 move() 函数(debugPrint 显示调用)。这在 0.4x 中工作,但显然在改进的 1.0 RiverPod 中我还没有完全迁移。

当状态是列表时,RiverPod 1.0 缺少什么来更新状态?

final animateCoversStateNotifierProvider = StateNotifierProvider.autoDispose<
    AnimateCoversStateNotifier,
    List<CoverAlignment>>((ref) => AnimateCoversStateNotifier());
class AnimateCoversStateNotifier extends StateNotifier<List<CoverAlignment>> {
  AnimateCoversStateNotifier() : super([]);

  void addCover({
    required CoverAlignment alignment,
  }) =>
      state.add(alignment);

  void move({
    required int cover,
    bool? readyToOpen,
    bool? speechBalloonVisible,
    Duration? animatedOpacityDuration,
    bool? removeSpeechBalloonPadding,
  }) {
    debugPrint('move cover called');
    Future.delayed(const Duration(milliseconds: 200), () {
      if (mounted) {
        state[cover].removeSpeechPadding = speechBalloonVisible != true;
        state[cover].speechBalloonOpacity =
            speechBalloonVisible == true ? kMaxSpeechBalloonOpacity : 0.0;
        state[cover].x = CoverAlignment.randomDouble();
        state[cover].y = CoverAlignment.randomDouble();
        state[cover].curve = CoverAlignment.getCurve();
        state[cover].seconds = CoverAlignment.randomSeconds();
        state[cover].degrees = CoverAlignment.randomIntInRangeWithMinimum(
          min: 0,
          max: 45,
        );
        /// This was required to update state using RiverPod 0.4x, but no longer works in 
        /// RiverPod 1.0.
        state = state;
      }
    });
  }
}

在我的构建屏幕正文中,我使用 watch 来响应通知程序的更改。

/// Display covers
final List coverAlignment =
    ref.watch(animateCoversStateNotifierProvider);

编辑:按照 Remi 在 cmets 中的建议创建 Freezed 类

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
import 'package:myapp/app/corral/models/cover_alignment_model.dart';

part 'animate_covers.freezed.dart';

class AnimateCovers extends StateNotifier<List<CoverAlignment>>
    with _$AnimateCovers {
  factory AnimateCovers() = _AnimateCovers;

  void addCover({
    required int cover,
    required CoverAlignment alignment,
  }) {
    state.insert(cover, alignment);
  }

  void move({
    required int cover,
    bool? readyToOpen,
    bool? speechBalloonVisible,
    Duration? animatedOpacityDuration,
    bool? removeSpeechBalloonPadding,
  }) {
    /// What do I do here?
  }
}

【问题讨论】:

    标签: flutter riverpod


    【解决方案1】:

    在做:

    state = state
    

    本来就不应该工作。

    你不应该改变现有的状态。你应该克隆状态

    改为:

    state[cover] = state[cover].copyWith(
      removeSpeechPadding: speechBalloonVisible != true,
      ...
    ),
    

    您可以使用Freezed 生成此copyWith 方法

    【讨论】:

    • 看着 Freezed pub.dev/packages/freezed Remi。在我的帖子中,我添加了创建 AnimateCoversStateNotifier 类的 Freezed 类的开始尝试。我不知道如何做到这一点。如果您能提供一些代码,将不胜感激。
    • 雷米,仍然坚持这一点。我尝试了几种不同的方法,当状态是列表时,RiverPod 1.0 似乎没有通知听众有关列表状态更改的信息。即使我可以让copyWith 工作,我也不明白这将如何导致 StateNotifier 在列表中发出更改。
    • 我确实找到了一种解决方法,因为我无法在 statenotifier 中更新状态。我使用 StatefulBuilder 并且能够调用 setState()。无论如何,不​​确定这是否是 RiverPod 1.0 中的问题。谢谢你所有令人难以置信的工作雷米。
    猜你喜欢
    • 2021-03-17
    • 2021-11-27
    • 1970-01-01
    • 2021-04-04
    • 2021-11-29
    • 2021-12-01
    • 1970-01-01
    • 2021-01-28
    • 2023-02-01
    相关资源
    最近更新 更多