14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Flutter] Navigator.pop()したときに画面を再描画するシンプルな方法

Last updated at Posted at 2020-09-06

やりたいこと

Navigator.pop()で画面を戻って来たときに再描画したい。色々なやり方があるようだが、ある程度実装を進めたので今の設計を崩したくない。画面遷移部分だけの実装で、再描画を実現したい。

やったこと

  • 公式ドキュメントのReturn data from a screenがほぼ全てだが、もとの画面に戻る際に値を受け取り、その値を見て再描画を実行する。
  • 呼び出し元画面でNavigator.push()の実行をasyncメソッドで実装し、await実行することで、呼び出し先画面から戻った際に、そのメソッドに戻るようにする。
  • あとはそのメソッド内で再描画をコールする。

ソースコード

今回は関連する部分のみ記述する。

まずは呼び出し元画面

FirstPage.dart
  @override
  Widget build(BuildContext context) {
    return Container(
    :
    child: RaisedButton( // [*1]
      onPressed: () {
        pushWithReloadByReturn(context);
      },
      child: Text("GoSecondPage"),
    );
  }

  void pushWithReloadByReturn(BuildContext context) async { // [*2]
    final result = await Navigator.push( // [*3]
      context,
      new MaterialPageRoute<bool>( // [*4]
        builder: (BuildContext context) => SecondPage(),
      ),
    );

    if (result) { // [*5]
      // setState(() {});
      // notifyListeners();
    }
  }
  1. 画面遷移するボタン。押下時に下で定義したasyncメソッドを呼び出している。
  2. asyncで画面遷移を実装したメソッド。次の画面からNavigator.pop()で戻った際に、このメソッドに返ってくる。
  3. awaitでNavigator.push()を呼ぶことで、画面が戻ってくるまでここで待ち続ける。
  4. 戻り値のクラスを<bool>に設定している。ここをStringや他のクラスにすることでいろいろな戻り値を受け取れる。今回はboolなので、当然[*3]のresultには、bool値が入る。
  5. あとはresultの値を見て、StatefulWidgetならsetState()、ChangeNotifierProviderを使用しているならnotifyListeners()といったように、再描画の処理を呼び出せば良い。

次に呼び出された画面

SecondPage.dart
  @override
  Widget build(BuildContext context) {
    return Container(
    :
    child: RaisedButton(
      onPressed: () {
        Navigator.pop(context, true); // [*1]
      },
      child: Text("ReturnFirstPage"),
    );
  }
  1. こちらはシンプルで、Navigator.pop()の第2引数(呼び出し元ページに返却する値)にbool値を渡すだけ。今回の例では、FirstPage側の実装で、この値を見て再描画するかどうかを判定させているので、ここでtrueを送れば戻った直後に画面が再描画され、falseを送れば再描画はされないことになる。

やってみて

いろいろな記事を調べて試行錯誤しつつ、最終的にこの方法にたどり着いたが、きちんとやるならNavigatorObserverを使ってdidPopなどを実装するほうが汎用性が高そうだった。まとまった時間が取れたら、一度全体的なリファクタリングを行いたい。

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?