【问题标题】:Flutter Dio Package: How to listen to download progress from another class?Flutter Dio Package:如何收听另一个类的下载进度?
【发布时间】:2020-10-04 06:45:47
【问题描述】:

我有一个DownloadsService 类,它使用dio 包处理文件下载。我想听听我的ViewModel 类的下载进度,该类在我的DownloadService 类中实现了downloadFile 方法。我该怎么做呢?

这是 DownloadsService 类的代码 sn-p:

class DownloadsService {
   final String urlOfFileToDownload = 'http://justadummyurl.com/'; //in my actual app, this is user input
   final String filename = 'dummyfile.jpg';
   final String dir = 'downloads/$filename'; //i'll have it saved inside internal storage downloads directory

   void downloadFile() {
     Dio dio = Dio();
     dio.download(urlOfFileToDownload, '$dir/$filename', onReceiveProgress(received, total) {
        int percentage = ((received / total) * 100).floor(); //this is what I want to listen to from my ViewModel class
     });
   }
}

这是我的ViewModel 课程:

class ViewModel {
   DownloadsService _dlService = DownloadsService(); //note: I'm using get_it package for my services class to make a singleton instance. I just wrote it this way here for simplicity..

      void implementDownload() {

       if(Permission.storage.request().isGranted) { //so I can save the file in my internal storage
          _dlService.downloadFile();

        /*
         now this is where I'm stuck.. My ViewModel class is connected to my View - which displays
         the progress of my download in a LinearProgressIndicator. I need to listen to the changes in
         percentage inside this class.. Note: my View class has no access to DownloadsService class. 
       */

      }        
   }
}

Dio 文档提供了如何将响应类型转换为流/字节的示例。但它没有提供任何示例说明如何在下载文件时执行此操作。有人能指出我正确的方向吗?我现在真的卡住了..非常感谢!

【问题讨论】:

    标签: flutter stream progress listen dio


    【解决方案1】:

    如果View创建了ViewModel,那么你必须在View类中定义PublishSubject变量,然后将其传递给ViewModel,并将其作为参数传递给 DownloadsService

    像这样:

    class ViewModel {
           PublishSubject publishSubject;
           ViewModel(this.publishSubject);
           DownloadsService _dlService = DownloadsService();   
              void implementDownload() { 
               if(Permission.storage.request().isGranted) {  
                  _dlService.downloadFile(publishSubject); 
              }        
           }
        }
    

    这样View会监听downloadFile方法之前发生的变化,依次发送变化

    像这样:

    void downloadFile(PublishSubject publishSubject) {
         Dio dio = Dio();
         dio.download(urlOfFileToDownload, '$dir/$filename', 
            onReceiveProgress(received,total) {
            int percentage = ((received / total) * 100).floor(); 
            publishSubject.add(percentage);
         });
       }
    

    让界面监听到之前会发生的变化

    像这样:

    class View {
      PublishSubject publishSubject = PublishSubject();
      ViewModel viewModel;
      View(){
        publishSubject.listen((value) {
          // the value is percentage.
          //can you refresh view or do anything
        });
       viewModel = ViewModel(publishSubject);
      }  
    }
    

    【讨论】:

    • 嘿伙计,感谢您的回复。我的 View 类真的只是我的 UI 代码。我绝对不想将任何业务逻辑放在我的 View 类中。我想做的是,我的 ViewModel 类将监听 DownloadsService 类,然后将该当前值传递给 View 类。所以我的 View 类唯一要做的就是在 UI 中显示数据。
    • 不客气,我明白你真正想要什么,你可以在'ViewModel'中定义'publishSubject'变量并监听'DownloadsService'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    相关资源
    最近更新 更多