43
30

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で前の画面に戻らせたくない時に使うwillPopScopeを紹介する

Posted at

概要

Webで言うところのPOSTでアクセスするような、ユーザーが1つ前の画面に戻ってほしくないシチュエーションがあると思います。
willPopScopeを使え、で終わりなのですが日本語の記事がなかった上に筆者の英語力がヘボ過ぎて英語の記事も見つけられなかったのでメモとして残します。

雑にtwitterで呟いたらへぶんさんが教えてくれました…圧倒的感謝…🙏

https://twitter.com/heavenOSK/status/1217020388552478723?s=20

解説

APIドキュメントを読めば説明するまでもないと思いますが、一応やってみます。

前提

こんな感じの画面があると仮定してください。ルーティングやスタイルの部分は省略します。
can-go-back.gif


class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面1')),
        bottomNavigationBar: BottomAppBar(
          FlatButton(
            onPressed: () => Navigator.of(context).pushNamed(Screen2.routeName),
            child: Text('次の画面に遷移する')
        ),
    );
  }
}


class Screen2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面2'))
    )
  }
}

gifが分かりにくいかもしれませんが、画面2から画面1に戻れてしまっていますが、今回はこれを制限します。

willPopScopeでラップする

やることは簡単で、遷移後のwidgetをwillPopScopeでラップしてください。
_willPopScope.onWillPopにはFuture<bool>を返す関数を登録しましょう。今回は戻ろうとした時に何もしないのでただtrueを返す虚無関数です。(voidではない)


class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _willPopCallback,
      child: Scaffold(
        body: Center(child: Text('画面1')),
        bottomNavigationBar: BottomAppBar(
          FlatButton(
            onPressed: () => Navigator.of(context).pushNamed(Screen2.routeName),
            child: Text('次の画面に遷移する')
        ),
      ),
    );
  }
  Future<bool> _willPopCallback() async {
    return true;
  }
}


class Screen2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面2'))
    )
  }
}

結果

ツールの都合上マウスポインタが見えないですが、右にスワイプしても画面遷移しなくなりました。

cannot-go-back.gif

willPopScopeの説明にも今開いているModalRouteを消す試みを拒否するコールバックを登録するとあるので、責務がこれだけで実装も非常に簡単ですね。お疲れ様でした。

Registers a callback to veto attempts by the user to dismiss the enclosing ModalRoute.

参考URL

43
30
1

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
43
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?