文系プログラマー「いお」が語る

主にプログラミング関連の記事を書いています。

【Flutter初心者用】画面遷移(pop)時におこる謎の黒い画面の正体について

こんにちは!文系プログラマーのいおです!

 

Flutterで画面遷移のプログラムを組んでいて、

エミュレーターでテスト中、

「戻る」ボタンを押下。

 

あれ、、、、

なんか真っ黒な画面が出て画面が動かなくなった…
なにこのブラックアウト…

このような状態になったことありませんか?

 

今回は、Flutterでの画面遷移の実装時に起きることのあるこの真っ黒な画面の原因についての記事です。

 

 

はじめに

Flutterの画面遷移の基本については下記記事を参考にしてみてください。

結論

はい、早速結論となりますが、これは画面遷移時の「スタック」が空になることで起こります。つまり、すべての画面ウィジェットがなくなった状態ということです。

 

どういうこと?

下記図1を用いて説明します。

図1

①②は、FirstPageからSecondPageへ「*pushReplacement()」メソッドを用いて画面遷移を行った場合のスタックの状態を表しています。③は②から「pop()」した後のスタックの状態です。

もう分かる方いるかもしれませんね。そうなんです、あの画面が真っ黒になる現象は図1のようにスタック、つまり画面ウィジェットが何もない状態になることで起こります。

 

*pushReplace()メソッドとは、一方通行で遷移したら前の画面には戻らない、といった要件の画面遷移を実現するためのメソッドです。例えば、起動画面やログイン画面などの実装で使われることがあります。

 

具体的なプログラム例

下記に黒い画面の出る例を示します。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget{
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(title: const Text('First Page')),
      body: Center(
        child: ElevatedButton(
          onPressed: (){
            Navigator.pushReplacement(context, MaterialPageRoute(builder: (context){
                return SecondPage();
              }),
            );
          },
          child: const Text('Next Page'),
        )
      ),
    );
  }
}

class SecondPage extends StatelessWidget{
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(title: const Text('Second Page')),
      body: Center(
          child: ElevatedButton(
            onPressed: (){
              Navigator.pop(context);
            },
            child: const Text('Back'),
          )
      ),
    );
  }
}

 

このサンプルを実行すると下記のように遷移します。

図2

 

まとめ

以上のように、Flutterアプリ開発時に遭遇するあの黒い画面の正体は「スタック」が空だから起こっていたんですね!

今回は2画面のシンプルなアプリケーションで説明しましたが、実際にはもっと多くの画面数があるものが普通だと思います。ですので、画面遷移を実装するときはスタックの状態がどのようになっているか、ということをきちんと意識してプログラムを組んでいく必要があります。

最後にですが、以下記事で紹介している本には今回解説したようなFlutterの概念や開発方法がわかりやすくまとめられているのでおすすめです。

 

以上です!最後までお読みいただきありがとうございました!