Flutter: ページを pop() したとき initState() は動かない

Flutter: ページを pop() したとき initState() は動かない

September 11, 2022

掲題について、根本的に勘違いしていたので、反省も込めてここにメモ。

検証コード #

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(
      home: const MyWidget1(),
      routes: <String, WidgetBuilder>{
        '/mywidgeet1': (BuildContext context) => const MyWidget1(),
        '/mywidgeet2': (BuildContext context) => const MyWidget2(),
      },
    );
  }
}

/*
  MyWidget1
*/

class MyWidget1 extends StatefulWidget {
  const MyWidget1({super.key});

  @override
  State<MyWidget1> createState() => _MyWidgetState1();
}

class _MyWidgetState1 extends State<MyWidget1> {
  int myCount1 = 0;

  @override
  void initState() {
    super.initState();
    myCount1++;
    print('myCount1 was incremented to $myCount1');
  }

  @override
  Widget build(BuildContext context) {
    print('MyWidget1 was built');

    return TextButton(
      onPressed: () => Navigator.of(context).pushNamed("/mywidgeet2"),
      child: const Text('Push'),
    );
  }
}

/*
  MyWidget2
*/

class MyWidget2 extends StatefulWidget {
  const MyWidget2({super.key});

  @override
  State<MyWidget2> createState() => _MyWidgetState2();
}

class _MyWidgetState2 extends State<MyWidget2> {
  int myCount2 = 0;

  @override
  void initState() {
    super.initState();
    myCount2++;
    print('myCount2 was incremented to $myCount2');
  }

  @override
  Widget build(BuildContext context) {
    print('MyWidget2 was built');

    return TextButton(
      onPressed: () => Navigator.of(context).pop("/mywidgeet1"),
      child: const Text('Pop'),
    );
  }
}

コンソール出力 #

# 初期表示時
myCount1 was incremented to 1
MyWidget1 was built

# MyWidget1 から myCount2 に push()
myCount2 was incremented to 1
MyWidget2 was built

# MyWidget2 から myCount1 に pop()
(なにも出力されない)

# MyWidget1 から myCount2 に push()
myCount2 was incremented to 1
MyWidget2 was built

# MyWidget2 から myCount1 に pop()
(なにも出力されない)

まとめ #

Flutter のページ遷移は push() & pop() でページの上にページを重ねていく形(または重ねたものを上から取り除く形)になります。

そのため pop() は上に乗っていたページが取り除かれてすでに開いているページがまた表示されるようになるだけで、新しくページが開かれるわけではありません。

従って initState() をはじめとしたライフサイクルメソッドが動かないのは当然ですね。