全体の流れ
StatefulWidgetは4つの状態を遷移させながら画面描画・リソースの解放を行なっています。
StatefulWidgetのソースを見てみると以下のように定義されています。
enum型の_StateLifecycle
という名前で管理されていますね。
/// Tracks the lifecycle of [State] objects when asserts are enabled.
enum _StateLifecycle {
/// The [State] object has been created. [State.initState] is called at this
/// time.
created,
/// The [State.initState] method has been called but the [State] object is
/// not yet ready to build. [State.didChangeDependencies] is called at this time.
initialized,
/// The [State] object is ready to build and [State.dispose] has not yet been
/// called.
ready,
/// The [State.dispose] method has been called and the [State] object is
/// no longer able to build.
defunct,
}
created
statefulWidgetのcreateState()
が呼び出されると状態がcreatedに遷移します。
cteate状態では状態の初期化を行うinitState()
が実行されます。
注意したいのは、このときはまだBuildContextが生成されていないということ。
BuildContextを使った初期化処理はinitState()
内では実行できません!
(筆者はこのルールを知らずにエラーを直すのにめちゃくちゃ時間がかかりました…😩)
initialized
initState()
が完了すると、状態がinitializedに遷移します。
initialized状態ではStateオブジェクトの依存関係に変化があった場合に呼び出されるdidChangeDependencies()
が実行されます。
didChangeDependencies()
の実行前にBuildContextの生成が行われるため、BuildContextを使った初期化処理はここで記述することになります。
initState()
がwidget初期化時に一度だけ呼び出されるのに対して、didChangeDependencies()
は依存関係が変わる(親widgetの変化とか)ごとに呼び出されます。
ready
didChangeDependencies()
の完了後、readyに遷移します。
初回構築時はwidgetを生成するbuild()
がそのまま実行されますが、親widgetの再構築後はdidUpdateWidget()
、Stateの変更時はsetState()
を経由してbuild()
が実行されます。
Stateオブジェクトがウィジェットツリーから削除されるたびにdeactivate()
が実行されます。この時点ではまだ再ビルドされる可能性があります。
defunct
widgetが完全に破棄された状態。
widgetがツリーから完全に削除され、二度とビルドされなくなったらdispose()
が実行され、リソースが解放されます。
dispose()
が実行された後、再ビルドする必要がなくなったWidgetはdefunct遷移します。
これであなたも今日からライフサイクルマスター💪
参考
最後に…
最後に少しだけ宣伝させてください。
株式会社Visionでは広報活動の一環として有志を募ってアプリを開発し、ついに先日リリースしました!(もちろんFlutterを使ってます!)
アプリ名は「過去イチ」
カテゴリごとに自分だけのランキングを作成して記録できます
第一弾ですので使える機能はかなり限られていますが、ご興味のある方はぜひ🙏
👇Android版
👇iOS版