動くコード図鑑技術記事現場の渡り方キャリア論すべての記事About
技術記事

Flutterでページ遷移をしたのに戻るボタンが表示されない場合のチェック項目!

バイブス父さん
現役の業務SE
2021年6月1日4 min read
Flutterでページ遷移をしたのに戻るボタンが表示されない場合のチェック項目!

みなさんこんにちは!ひろぽんです!

最近は自社開発案件でFlutterを使用してアプリ開発をしていますが、Flutter自体めちゃくちゃ楽しい言語だなーーと思います!!

音楽を聴きながらコーディングをしていたら知らない間に数時間経過というのもあるくらい楽しいです!!

さて今回はそんなFlutterで1時間ほどはまった画面遷移をしているのに戻るボタンが表示されない問題について書いていきたいと思います!

結論!MaterialAppはルートでしか使用してはダメ!

チュートリアルが終わっていざコーディングってなったときに、ページごとのルートにMaterialAppをいれていませんか??

戻るボタンが表示されないのはそれが原因です!!

Flutterでは通常画面遷移をしたら戻るボタンが表示される

Googleで「Flutter 画面遷移」と調べると大体下記の2つの方法が出てきます。

Navigator.pushでの画面遷移

onPressed: (){
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => NextPage(),
              )
            )

Routerでの画面遷移

onPressed: (){
            Navigator.pushNamed(context, '/next');
          },

通常は下記のように戻るボタンが表示される!

戻るボタンが表示されなかったコードは下記

戻るボタンが表示されなかったコードは下記 (javascript)#3998d78aefb5
class View1 extends StatelessWidget {
  const View1({Key key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "View1",
      home: Scaffold(
        appBar: AppBar(title: Text('View2'),),
        body: Center(child: Text('View2'),),
        floatingActionButton: ElevatedButton(onPressed: () =>
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => View2()
                )
            ),
        ),
      ),
    );
  }
}
 
class View2 extends StatelessWidget {
  const View2({Key key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "View1",
      home: Scaffold(
        appBar: AppBar(title: Text('View2'),),
        body: Center(child: Text('View2'),),
      ),
    );
  }
}
▸ この snippet は実行結果未収録
▸ 実行結果は未収録です

原因:MaterialAppはルートに一つだけしか存在してはいけないというルールがあった

このコードの一番の問題は冒頭にも書いた通り、MaterialAppはルートにしか存在してはいけないという事なのです。

上記のコードでは、ページごとにMaterialAppが存在しているので、contextに画面遷移の情報が保持されず戻るボタンが表示されていないのでは?と推察します。

なので、下記のように修正すると戻るボタンは表示されます。

原因:MaterialAppはルートに一つだけしか存在してはいけないというルールがあった (javascript)#9d46e68f422a
class View1 extends StatelessWidget {
  const View1({Key key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('View2'),),
        body: Center(child: Text('View2'),),
        floatingActionButton: ElevatedButton(onPressed: () =>
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => View2()
                )
            ),
        ),
      );
  }
}
 
class View2 extends StatelessWidget {
  const View2({Key key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('View2'),),
      body: Center(child: Text('View2'),),
    );
  }
}
▸ この snippet は実行結果未収録
▸ 実行結果は未収録です

MaterialAppを外しPageのルートではScaffoldを返すようにします。

これで、戻るボタンが表示されます。

この記事のコードと手順は ぜんぶ動作検証済み。 安心して現場で試してくれ。
バイブス父さん

現役の業務SE。C# / SQL Server 保守の現場から、コードも人もキャリアも全部書く。 実体験ベース。

運営者について