はじめに
この記事は「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)