Флаттер показывает прогресс HUD при выполнении фоновой задачи

Я делаю приложение для создания фильмов, в котором я показываю прогресс при создании фильма из списка видеороликов. Но индикатор прогресса прогресса HUD застрял в начальной точке. Ниже приведен мой код:

    class _MyHomePageState extends State<MyHomePage> {
      static List<dynamic> videosPath = List();

      static const MethodChannel methodChannel =
          const MethodChannel('moviemaker.devunion.com/movie_maker_channel');

      String _batteryLevel = 'Battery level: unknown.';
      ProgressHUD _progressHUD;
      bool _loading = false;

      @override
      void initState() {
        super.initState();
    //    _getBatteryLevel();

        _progressHUD = new ProgressHUD(
          backgroundColor: Colors.black12,
          color: Colors.white,
          containerColor: Colors.blue,
          borderRadius: 5.0,
          text: 'Loading...',
          loading: false,
        );
      }

      @override
      Widget build(BuildContext context) {
        Widget child = new Scaffold(
          appBar: new AppBar(
            title: new Text('Movie Maker'),
            actions: <Widget>[
              // action button
              IconButton(
                icon: Icon(Icons.movie_creation),
                onPressed: () {
                  _createMovieSync(videosPath);
                },
              )
            ],
          ),
          body: Stack(children: [_progressHUD, _buildContentSection()]),
          floatingActionButton: new FloatingActionButton(
            onPressed: () {
              debugPrint("Bipin - FAB pressed");
              pickVideos().asStream().listen(_setResults);
            },
            tooltip: "Pick a Video",
            child: new Icon(Icons.add),
          ),
        );

        return child;
      }


  void toggleProgressHUD() {
    setState(() {
      if (_loading) {
        _progressHUD.state.dismiss();
      } else {
        _progressHUD.state.show();
      }
      _loading = !_loading;
    });
  }

void _createMovieSync(List<dynamic> paths) {
    toggleProgressHUD();
    _createMovie(videosPath).then((moviePath) {
      debugPrint("Bipin - _createMovieSync Movie created path: $moviePath");
      _startMovie(moviePath).then((_) {
        debugPrint("Bipin - start movie then");
      }).catchError((error) {
        debugPrint("Bipin - start movie error:");
      }).whenComplete(() {
        debugPrint("Bipin - start movie completed.");
        toggleProgressHUD();
      });
    }).catchError((error) {
      debugPrint("Bipin - Create movie error: ${error.toString()}");
    }).whenComplete(() {
      debugPrint("Bipin - Create movie completed.");
    });
  }

  Future<String> _createMovie(List<dynamic> paths) {
    return Future<String>(() {
      debugPrint("Bipin - Create movie future going to sleep");
      sleep(Duration(seconds: 10));
      debugPrint("Bipin - Create movie future wake up");
      return "FilePath goes here";
    });
//    return methodChannel.invokeMethod('createMovie', {"videoPaths": paths});
  }

  Future<Null> _startMovie(String moviePath) async {
    return Future<Null>(() {
      debugPrint("Bipin - Start movie future going to sleep");
      sleep(Duration(seconds: 10));
      debugPrint("Bipin - Start movie future wake up");
    });
//    debugPrint("Bipin - Created Movie path: $moviePath");
//    return methodChannel.invokeMethod('startMovie', {"moviePath": moviePath});
  }

Здесь я начинаю создание фильма, когда пользователь нажимает на Create Movie кнопка действия и показывает прогресс HUD, но он не работает, как ожидалось, он показывает, как здесь.

Обновленный код для использования modal_progress_hud 0.0.6, Как предложено в ответе, но это все еще, показывая, висит прогресс HUD. Найдите код здесь: https://github.com/bipinvaylu/MovieMaker-Flutter/commit/43b317efc9fdbc6e67cf36b16e4350587bf517ae

1 ответ

Я использую немного другой подход с пакетом modal_progress_hud, который оборачивает виджет, который вы хотите сделать модальным (с индикатором прогресса). После возврата асинхронного вызова вы выключите индикатор выполнения. Затем вы можете воспроизвести фильм.

Независимо от того, какой пакет вы используете, я бы, вероятно, переключился на другой виджет, чтобы воспроизвести фильм, вызванный вызовом setState() после выполнения вызова, чтобы остановить индикатор прогресса. Воспроизведение фильма до завершения исходного асинхронного вызова может препятствовать остановке индикатора выполнения. Пища для размышлений.

Другие вопросы по тегам