はじめに
この記事は「Fragments: Rebuilding the Internals」の内容を、自分が理解できるように翻訳したりメモしたりした備忘録です。
概要
FragmentManagerの内部実装が変わった。
FragmentStateManagerについて説明されている。
本文
Androidフレームワークの方のFragmentを使ってはいけない
Androidフレームワークの方のFragmentは、Android 10 で非推奨になった。
絶対にAndroidXの方を使う。
Fragment 1.3.0-alpha08 で FragmentManagerの重要なところが(内部的に)作り直された
FragmentManagerが直接扱っていたロジックを、内部クラスで置き換えた。
その内部クラスがFragmentStateManagerである。
(個人的には内部クラスに切り出されたというイメージ🤔)
FragmentStateManagerができて何が嬉しいのか
- ロジックが簡単になった
- テストしやすくなった
- メンテナンスしやすくなった
Note: Fragment 1.3.0-alpha08 にバージョンアップしたら、VRT(ビジュアルリグレッションテスト)に気をつけよう。
FragmentStateManager が担っていること
- Fragmentのライフサイクルに応じた遷移
- アニメーションとトランジションの実行
- 延期されたトランザクションの処理
💡💡💡
1つのFragmentManagerが複数のバックスタックを持てるようになった。
(Fragmentのライフサイクルが簡単になったともある)
FragmentManager’s moveToState()
ActivityがCREATED,STARTED,RESUMEDに移動すると、FragmentManagerはそれらの変更をFragmentに送る。
これがmoveToState()の役割である。
moveToState()は単純ではなく、ネストしている全てのFragmentの状態を判断するためのロジックはたくさんある。
このmoveToState()のロジックを1つにまとめて簡単にするため、FragmentStateManagerが誕生した。
それぞれのFragmentはFragmentStateManagerに紐づいていて、FragmentManagerは直接Fragmentとやりとりするのではなく、FragmentStateManagerをやりとりするようになる。
この役割分担によって、それぞれのFragmentの状態を判断するためのロジックを1つに集約することができるメソッドを作ることができた。
それがcomputeExpectedState()である。
98% の場合、ホスト/親フラグメントと同じ状態になる。
裏を返せば、2% でホスト/親フラグメントと違う状態になる。
🤔🤔🤔
しかし、正しい状態を判断する方法がない場合に遭遇したらしい。
Postponed fragments
いろいろ翻訳したりメモしたりしたが、保存し忘れて消えました🙃
遅延されたFragmentを扱う時にいろいろバグあり、それを修正したそうです。
Working at the container level
コンテナレベルで、Fragmentのイン/アウトのアニメーションをする時に問題が起こる。
Fragmentはいくかのアニメーションシステムをサポートしている。
- The old and busted framework Animation API
- The framework Animator API
- The framework Transition API (only API 21+, also pretty busted)
- The AndroidX Transition API
これらをまとめて操作できるクラスを作って、SpecialEffectsControllerと命名した。
SpecialEffectsControllerはコンテナに1つだけある。
つまり、一番上に追加されたフラグメントが延期されると、コンテナ全体が延期されます。
FragmentManager内に散らばっていたアニメーションのロジックをDefaultSpecialEffectsControllerにまとめことができた。
So what does a ‘new state manager’ mean
FragmentManagerの内部を分割することで、それぞれのレイヤーのロジックを簡単にすることができた。
-
FragmentManagerは、すべてのフラグメントに適用される状態のみを持っている。 -
FragmentStateManagerは、フラグメントレベルの状態を管理する。 -
SpecialEffectsControllerはコンテナレベルで状態を管理する。
Should I expect behavior changes?
これまでのFragmentの振る舞いが変わってしまいますか?
→変わらない
(大事そうなところだけ抜粋)
アニメーションやトランジションが完了するまで、そのFragmentの状態はSTARTEDのままになる。
What if I do see behavior changes?
これまでのFragmentの振る舞いが変わったらどうすればいい?
Fragment 1.3.0-alpha08から、デフォルトでFragmentStateManagerが動作する。
FragmentStateManagerのせいで振る舞いが変わっているか調査しましょう。
以下のコードでFragmentStateManagerを無効にできる。
FragmentManager.enableNewStateManager(false)