Flutter Riverpod 在没有上下文的情况下设置值

Posted

技术标签:

【中文标题】Flutter Riverpod 在没有上下文的情况下设置值【英文标题】:Flutter Riverpod Setting a Value Without Context 【发布时间】:2021-03-20 21:17:05 【问题描述】:

我有一个应用程序,其中需要在 Feed 屏幕上显示视频上传进度指示器。返回上传进度的代码位于视频客户端类中,该类不在 Feed 屏幕的小部件树中,并且在视频开始上传时 Feed 屏幕甚至没有打开。

我要做的是使用 Riverpod 在视频客户端类中全局更新上传值,以便在打开提要屏幕时显示上传进度。

问题是视频客户端是一个单独的类,没有任何构建上下文,我正在尝试更新值。我听说 Riverpod 可以在没有构建上下文的情况下设置状态。但我能看到的唯一更新状态的方法仍然需要上下文。

在主函数中,我在这里添加提供者范围:

void main() 
  FlowRouter.setupRouter();
  runApp(ProviderScope(child: MyApp()));

我有一个上传模型,它扩展了更改通知器以更新值:

class UploadModel extends ChangeNotifier

  UploadModel();

  int _bytesTotal = 0;
  int _bytesUploaded = 0;
  bool _uploadVisible = false;
  
  void setBytesTotal(int value)
    _bytesTotal = value;
    notifyListeners();
  
  int get getBytesTotal => _bytesTotal;
  
  void setBytesUploaded(int value)
    _bytesUploaded = value;
    notifyListeners();
  
  int get getBytesUploaded => _bytesUploaded;
  
  void setUploadVisible(bool value)
    _uploadVisible = value;
    notifyListeners();
  
  bool get getUploadVisible => _uploadVisible;

在 Feed 小部件中,我有以下代码可以查看和更新​​上传小部件:

final uploadProvider = riverpod.ChangeNotifierProvider((ref) => UploadModel());

class  UploaderProgressWheel extends riverpod.ConsumerWidget 
  @override
  Widget build(BuildContext context, ScopedReader watch) 

    final uploadInfo = watch(uploadProvider);

    return Text(uploadInfo.getBytesUploaded.toString());

但是当我去更新视频客户端类中的上传值时,我看不到任何不需要上下文的方法,我想我需要像这样再次在视频客户端类中添加提供程序:

final uploadProvider = riverpod.ChangeNotifierProvider((ref) => UploadModel());

然后我想从 UploadModel 类中使用 setBytesUploaded() 访问设置值,但我无权访问它,我发现的唯一示例如下所示,需要上下文:

context.read(uploadProvider).state = 

谢谢

【问题讨论】:

帮助我更多地理解您的代码,您想在 UploadModel 更新其值时更新您的 VideoClient 类吗?这个 VideoClient 是一个单例实例,还是您也使用提供程序创建它?最好的解决方案是创建一个 Provider((ref) => VideoClient(ref.watch(uploadProvider.getBytesUploaded)));也许更多 VideoClient 类的代码会有所帮助 您好,感谢您的回复。没有构建上下文的视频客户端类上传视频,它跟踪并定期返回上传的字节。所以我想在每次视频客户端返回上传的字节时更新上传模型。提要小部件正在监视上传模型的更改,以使用进度指示器更新用户体验。 不幸的是,视频客户端类很大,所以我不能在这里发布。但基本上它只是将视频上传到服务器返回上传进度,然后返回成功或失败。 【参考方案1】:
class VideoClient  //Example class
   final Reader read; //so you can read other providers inside this
   int _i = 0; //just for example

   VideoClient(this.read);

   void exampleMethod()
     read(uploadProvider).setBytesUploaded(_i++);
     // each time this method is called a new int is sent to notify the uploadModel
   

   //.... your methods


final VideoProvider = Provider((ref) => VideoClient(ref.read)); // to have a single instance of your VideoClient across all your app

现在,当您想上传视频或使用 VideoClient 执行特定操作时,您可以从应用程序的任何位置调用此提供程序

RaisedButton(
  onTap: () 
    context.read(VideoProvider).upload(); //or whatever method you use to initilize an action
  
);

【讨论】:

最终读者阅读; //所以你可以在这个int _i = 0中读取其他提供者; //例如 VideoClient(this.read); 以上内容不是要求读者通过课堂吗? VideoProvider 会为您做到这一点

以上是关于Flutter Riverpod 在没有上下文的情况下设置值的主要内容,如果未能解决你的问题,请参考以下文章

使用新的 Flutter 2.2.2 版本为 Riverpod 运行“flutter pub get”时版本解决失败

重走Flutter状态管理之路—Riverpod入门篇

重走Flutter状态管理之路—Riverpod入门篇

Flutter状态管理之Riverpod

Flutter 将 Hive 数据库与 Riverpod 集成

Flutter 用 provider 和 riverpod 制作表单