title: How to multiple video download in Flutter
body: <p>I have to try to multiple video download functionality in a flutter and it works fine but I have to implement listview with ListTile and a right side download icon. If the user has clicked the download icon then Hide the download icon and show small progress to start the download. but it's not working and the progress bar does not show I mean UI not refresh at that time.</p>
  
  <p>Thanks in advance</p>
  
  <p>This is my Main Screen</p>
  
  <pre><code>    import 'dart:async'; 
      import 'dart:io';
      import 'package:dowload_sample/Golbals.dart';
      import 'package:dowload_sample/VideoModel.dart';
      import 'package:dowload_sample/database_helper.dart';
      import 'package:dowload_sample/test.dart';
      import 'package:flutter/material.dart';
      import 'package:flutter/widgets.dart';
      import 'package:flutter_downloader/flutter_downloader.dart';
      import 'package:path/path.dart';
      import 'package:path_provider/path_provider.dart';
      import 'package:scoped_model/scoped_model.dart';
  
      class HomePageNew extends StatefulWidget {
        @override
        _HomePage createState() =&gt; _HomePage();
      }
  
      class _HomePage extends State&lt;HomePageNew&gt; {
        VideoModel myModel = new VideoModel();
  
        VideoDownloader downloader;
  
        @override
        void initState() {
          // TODO: implement initState
          myModel.fetchVideoListFromDatabase();
          super.initState();
          this.downloader = new VideoDownloader();
        }
  
  
        @override
        Widget build(BuildContext context) {
          this.downloader = new VideoDownloader();
          return new Scaffold(
            backgroundColor: Colors.grey,
            appBar: new AppBar(
              title: new Text(
                'Multiple Downloader Demo',
                style: new TextStyle(color: Colors.white),
              ),
              actions: &lt;Widget&gt;[
                new IconButton(
                  icon: new Icon(
                    Icons.add,
                    color: Colors.black,
                  ),
  
                ),
              ],
              backgroundColor: Colors.green,
            ),
            body: ScopedModel&lt;VideoModel&gt;(
              model: myModel,
              child: _buildListView(),
            ),
          );
        }
  
        _buildListView() {
          return ScopedModelDescendant&lt;VideoModel&gt;(
            builder: (BuildContext context, Widget child, VideoModel model) {
              final userList = model.users;
              return ListView.builder(
                itemBuilder: (context, index) =&gt; InkWell(
                      splashColor: Colors.blue[300],
                      child: _buildListTile(userList[index], index),
                      onTap: () {
                        print("Video Name: ${userList[index].videoName}");
                      },
                    ),
                itemCount: userList.length,
              );
            },
          );
        }
  
        _buildListTile(VideoModel userModel, int index) {
          return Card(
            child: ListTile(
              leading: Icon(Icons.video_label),
              title: Text(userModel.videoName),
              trailing: new ScopedModelDescendant&lt;VideoModel&gt;(builder:
                  (BuildContext context, Widget child, VideoModel videosModel) {
                final isList = videosModel.users;
                if (isList[index].state == VideoeState.downloading) {
                  print("Progress Icon");
                  return new Container(
                      height: 32.0,
                      width: 32.0,
                      child: new Padding(
                        padding: EdgeInsets.all(6.0),
                        child: new CircularProgressIndicator(
                            strokeWidth: 2.0, value: videosModel.downloadProgress),
                      ));
                } else if (isList[index].state == VideoeState.toDownload) {
                  if (isList[index].videoLocalURL == "" &amp;&amp;
                      isList[index].videoLocalURL.length == 0) {
                    print("Download Icon");
                    return new Container(
                        height: 32.0,
                        width: 32.0,
                        child: new IconButton(
                            icon: new Icon(Icons.cloud_download),
                            onPressed: () {
                              setState(() {
                                Globals.videoID = isList[index].videoID.toString();
                                downloader.performDownloadVideo(
                                    isList[index].videoLiveURL,
                                    isList[index].videoName,
                                    isList[index]);
                              });
                            }));
                  } else {
                    print("Play Icon");
                    return new IconButton(
                        icon: new Icon(Icons.play_arrow),
                        onPressed: () {
                          print(
                              "Going to play Video ${isList[index].videoName} from ${isList[index].videoLocalURL}");
                        });
                  }
                } else {
                  print("Play Default Icon");
                  return new IconButton(
                      icon: new Icon(Icons.play_arrow),
                      onPressed: () {
                        // Ellipsis
                        print(
                            "Going to play Video ${videosModel.videoName} from ${videosModel.videoLocalURL}");
                      });
                }
              }),
            ),
          );
        }
      }
  
      class DownloadInfo {
        VideoModel model;
        String taskId;
        String filePath;
  
        DownloadInfo({this.model, this.taskId, this.filePath});
      }
  
      class VideoDownloader {
        List&lt;DownloadInfo&gt; _downloadInfoList;
  
        VideoDownloader() {
          this._downloadInfoList = new List();
          FlutterDownloader.registerCallback((id, status, progress) {
            DownloadInfo downloadInfo = this.getDownloadInfoFromTaskId(id);
            if (downloadInfo != null) {
              if (status == DownloadTaskStatus.running) {
                downloadInfo.model.setState(VideoeState.downloading);
                downloadInfo.model.setDownloadProgress(progress / 100.0);
              } else if (status == DownloadTaskStatus.complete) {
                downloadInfo.model.setState(VideoeState.downloaded);
                downloadInfo.model.setDownloadProgress(1.0);
              } else {
                downloadInfo.model.setState(VideoeState.toDownload);
                downloadInfo.model.setDownloadProgress(0.0);
              }
            }
            print(
                'Download task ($id) is in status ($status) and process ($progress)');
            if (progress == 100) {
              DatabaseHelper.updateLocalVideoPath(
                  "${Globals.filePath}${"/" + Globals.fileName}", Globals.videoID);
            }
          });
        }
  
        Future&lt;void&gt; performDownloadVideo(
            String liveURL, String videoName, VideoModel video) async {
          var link = liveURL;
          var path = await getVideosDirectoryPath();
          var filename = videoName + ".mp4";
  
          print("Downloading $link as $filename in $path");
          Globals.filePath = path;
          Globals.fileName = filename;
  
          String taskId = await FlutterDownloader.enqueue(
            url: link,
            savedDir: path,
            fileName: filename,
            showNotification: true,
          );
  
          return _downloadInfoList.add(new DownloadInfo(
            taskId: taskId,
            model: video,
            filePath: join(path, filename),
          ));
        }
  
        Future&lt;void&gt; onComplete(DownloadInfo downloadInfo) async {
          downloadInfo.model.setLocalFilePath(downloadInfo.filePath);
        }
  
        DownloadInfo getDownloadInfoFromTaskId(String taskId) {
          if (this._downloadInfoList.length &lt; 1) return null;
          return this
              ._downloadInfoList
              .firstWhere((dli) =&gt; dli.taskId == taskId, orElse: () =&gt; null);
        }
  
        static Future&lt;String&gt; getVideosDirectoryPath() async {
          final directory = await getApplicationDocumentsDirectory();
          final String videosPath = join(directory.path, "videos");
          // Creating directory
          await new Directory(videosPath).create(recursive: true);
          return videosPath;
        }
      }
  
  
  This is Model Class
  
  import 'dart:convert';
  
  import 'package:dowload_sample/HomePage.dart';
  import 'package:dowload_sample/database_helper.dart';
  import 'package:flutter/material.dart';
  import 'package:scoped_model/scoped_model.dart';
  
  enum VideoeState { toDownload, downloading, downloaded, playing, paused }
  
  class VideoModel extends Model {
    String videoID = null;
    String videoName = null;
    String videoLiveURL = null;
    String videoLocalURL;
    VideoeState state;
    double downloadProgress;
    String localFilePath;
  
    VideoeState get state1 =&gt; this.state ?? VideoeState.toDownload;
  
    VideoModel(
        {this.videoID,
          @required this.videoName,
          @required this.videoLiveURL,
          @required this.videoLocalURL});
  
    VideoModel.map(dynamic obj) {
      this.videoID = obj["videoID"];
      this.videoName = obj["videoName"];
      this.videoLiveURL = obj["videoLiveURL"];
      this.videoLocalURL = obj["videoLocalURL"];
      this.state = VideoeState.toDownload;
      this.downloadProgress = 0.0;
    }
  
  
    void setState(VideoeState state) {
      this.state = state;
      notifyListeners();
    }
  
  
    List&lt;VideoModel&gt; _userList = [];
  
    List&lt;VideoModel&gt; get users =&gt; _userList;
  
    set _users(List&lt;VideoModel&gt; value) {
      _userList = value;
      notifyListeners();
    }
  
    double get downloadProgress1 =&gt; this.downloadProgress ?? 0.0;
  
    void setDownloadProgress(double x) {
      this.downloadProgress = x;
      notifyListeners();
    }
  
    String get localFilePath1 =&gt; this.localFilePath;
  
    void setLocalFilePath(String filePath) {
      if (filePath == null) {
        return;
      }
      this.localFilePath = filePath;
      if (this.state == VideoeState.downloading ||
          this.state == VideoeState.toDownload) {
        this.state = VideoeState.downloaded;
      }
      notifyListeners();
    }
  
    Map&lt;String, dynamic&gt; toMap() {
      var map = new Map&lt;String, dynamic&gt;();
      map["videoID"] = videoID;
      map["videoName"] = videoName;
      map["videoLiveURL"] = videoLiveURL;
      map["videoLocalURL"] = videoLocalURL;
      return map;
    }
  
    //Fetch data from the local data base
    Future&lt;List&lt;VideoModel&gt;&gt; fetchVideoListFromDatabase() async {
        DatabaseHelper dbHelper = DatabaseHelper();
        _users = await dbHelper.getAllVideoList();
        print("Length ${_userList.length}");
        notifyListeners();
        return _userList;
    }
  
  }
  
      enter code here
  </code></pre>