質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

Flutter ページ遷移するまでの時間スピナーを表示させたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 167

moriman

score 92

ページ遷移するまで時間がかかる場合にスピナー(CircularProgressIndicator())
を表示させたいです。

https://flutter.dev/docs/cookbook/plugins/play-video

スピナー表示に関しては上記ページで動画再生準備完了までの間スピナーを表示するサンプルがあるのですが、FutureBuilderを使っており、futureに関してはVideoPlayerControllerクラスを使えば、その中で自動的に用意してくれるので、それをFutureBuilderの引数に設定すれば、それだけでできる、ということらしいです。

ということで、そういうのを用意してくれていれば、それを使えばいいと思うのですが。
つまり、今回の場合、ページ遷移した時にコンプリートするfutureを用いてFutureBuilderを作る必要があるのだと思うのですが。
このfutureは自分で実装するしかないのでしょうか?

「ページ遷移するまでスピナー表示させたい」という要求自体かなり一般的な気がするので、すでにそういうfutureを作る仕組みが用意されているのならそれを使いたいのですが、あるんでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • tepci

    2020/07/10 12:03

    ページ遷移するまで時間がかかるのは具体的にどんな処理が原因でしょうか?
    例えばサーバーとの通信や、ファイル読み書きなどがあります。ただ単に〇秒待ったあとにのFutureを返すメソッドも作ることもできます。

    キャンセル

  • moriman

    2020/07/10 12:20

    回答を頂きましてありがとうございます。

    今回は、「一覧リスト表示画面」と「動画再生画面」がありまして、
    「一覧リスト表示画面」内のボタンを押す(ファイルを選択)

    「一覧リスト表示画面」で選択されたファイルを作成(10秒程度)

    作成完了後「動画再生画面」へ遷移。その際作成したファイルを
    引数として渡す。

    「動画再生画面」で再生準備完了までの間スピナー表示(1秒程度)

    動画再生

    という流れで、ファイル作成で時間がかかっているのにその間はスピナーも何もなく「一覧リスト表示画面」が表示されているだけなので、ユーザーも「え?動いてるの?」という感じです笑

    対応としては
    (1)「一覧リスト表示画面」で、ページ遷移で完了するfutureを作ってスピナーを表示させる。
    (2)「動画再生画面」でファイルを作成し、「ファイル作成→動画再生準備」が完了した時にコンプリートするfutureを作る→スピナーを表示。

    上記の選択肢が頭に浮かぶのですが、(2)に関して、firebase_storageにあるファイルをクライアント側で作成(複製)するのは非同期処理になると思うのですが、
    「動画再生画面」ウィジェットのbuild()メソッド内でawaitが使えない気がします。なので(2)の選択肢は不可能なんですかね?
    であれば(1)になるのですが、ページ遷移完了でコンプリートするfutureの作り方がわかりません。

    キャンセル

  • tepci

    2020/07/10 13:41

    少し整理させてください。

    対応策(1)
    1.「一覧リスト表示画面」で動画一覧を表示。
    2.動画を選択するとstorageから動画をダウンロード(ダウンロードされるまでスピナー表示)
    3.ダウンロード完了後、「動画再生画面」へ遷移
    4.再生準備完了されるまでスピナー表示

    対応策(2)
    1.「一覧リスト表示画面」で動画一覧を表示。
    2.動画を選択すると「動画再生画面」へ遷移
    3.遷移後、storageから動画をダウンロード(ダウンロード→再生準備完了までスピナー表示)

    以上のような順序の認識で間違いないですか?

    キャンセル

  • moriman

    2020/07/10 14:21

    はい、そのように考えています。

    ただやはり(2)の場合、「動画再生画面」ウィジェットのbuild()メソッド内でファイルを複製(ダウンロード)する処理はできないんですよね。(awaitが使えない。)

    ただ、VideoPlayerの準備も非同期処理のはずで、それはできているので、結局ファイル複製(ダウンロード)もどうにかしたらできるはず、だとは思うのですけどね。

    キャンセル

回答 1

checkベストアンサー

0

(1)も(2)も実現可能です。

(1)に関しては「ページ遷移で完了」ではなく、「ファイル作成で完了」という考え方にシフトしたほうがやりやすいと思います。ボタン押下時、ファイルダウンロード完了時にsetStateでスピナー表示/非表示を切り替えるなど。

イメージ↓
動画選択時の処理

bool _loading = false;

void _downloadVideo() async {
  // スピナー表示
  setState(() => _loading = true);
  _file = await xxxxxxxxxxxx().then((data) {
    // ダウンロード終了後
    // スピナー非表示
    setState(() => _loading = false);
    // 画面遷移
    Navigator.xxxxxxxxxxxxxxxxxxxxxxxxxx;
  });
}

...
  child: _loading
    ? CircularProgressIndicator() // _loadingがtrueならスピナー表示
    : VideoListView(),  // falseなら一覧表示
...

スピナーをオーバーレイ表示にしたい場合はこっちが向いている?

(2)は、FutureBuilderssnapshot.hasDatafalseの時はスピナー表示、trueになったらスピナーを消すという風にやればいいと思います。

イメージ↓

...
    child: FutureBuilder(
      future: _downloadVideo,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          // ダウンロード完了したら動画再生画面を表示
          return VideoPlayerView();
        } else if (snapshot.hasError) {
          // エラー表示
          return Error();
        } else {
          // ダウンロード完了するまではスピナー表示
          return CircularProgressIndicator();
        }
      },
    ),
...

Future<File> _downloadVideo() async {
  // ファイルダウンロード
  _file = await xxxxxxxxxxxxxxxxxx();
  // ファイル準備
  return await xxxxxxxxxxxxxx(_file );
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/17 08:16

    (1)の方法でスピナー出せました。
    非常に便利なパッケージですね。
    (2)も期を見てやってみようと思います。
    本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る