Fragment 同士の遷移時アニメーションで Predictive back を有効にする時の実装メモです。
これを書いている時点では、alpha 版のライブラリや Experimental な機能を使用しているため、将来的に変更される可能性があります。
実装
依存関係
ライブラリの依存は以下のバージョン以降である必要があります。
- Fragment 1.7.0 以降 or Transition 1.5.0 以降
- compileSdk 34
- material-components の Motion を使いたいならば 1.12.0 以降
Predictive back の有効
AndroidManifest で Predictive back を有効にします。
<!-- Application 全体で有効 -->
<application
...
android:enableOnBackInvokedCallback="true" />
<!-- or Activity 単位で有効 -->
<activity
...
android:enableOnBackInvokedCallback="true" />
次に Fragment で Predictive back を有効にします。
この有効は Application の onCreate
もしくは Activity の super.onCreate
の前に設定する必要があります。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
FragmentManager.enablePredictiveBack(true)
super.onCreate(savedInstanceState)
...
}
}
遷移アニメーションの実装
Jetpack の Navigation ではデフォルトでは遷移時のアニメーションが入っておらず、Predictive back を有効にしただけでは遷移時のアニメーションや連携は機能しません。
また、Fragment のスタックを独自で管理している場合も Predictive back は機能しないので、Jetpack の Navigation か FragmentManager を使っている必要があります。
パターン 1 : Navigation Component で遷移時アニメーションを設定する
Navigation Component で遷移時のアニメーションを設定するパターンです。
<navigation ...>
<fragment ...>
<action
...
app:enterAnim="@animator/nav_default_enter_anim"
app:exitAnim="@animator/nav_default_exit_anim"
app:popEnterAnim="@animator/nav_default_pop_enter_anim"
app:popExitAnim="@animator/nav_default_pop_exit_anim" />
</fragment>
</navigation>
パターン 2 : Transition でアニメーションを設定する
Transition で標準で用意されている AutoTransition
を設定して Fragment が表示するときのアニメーションを設定するパターンです。
AutoTransition
で適用されるアニメーション自体は Fade になっています。
class FragmentA: Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = AutoTransition()
reenterTransition = AutoTransition()
}
}
class FragmentB: Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = AutoTransition()
exitTransition = AutoTransition()
}
}
material-components の Motion にある Transition 系の API を使っている場合、Predictive back がサポートされているライブラリバージョンを使っているならば追加実装なしで機能します。
パターン 3 : Shared element transition を設定する
Transition を使用する Shared element transition もパターン 2 同様に機能します。
ただし、設定できる Transition に制限があり、Transition の実装クラスで isSeekingSupported = true
であるものが Predictive back に対応しています。
また、Shared element trantision の Transition だけでなく、enterTransition
のような通常の Transition も設定する必要があります。
// In FragmentA
binding.card.setOnClickListener {
val extras = FragmentNavigatorExtras(
it to "shared_element_container",
binding.icon to "shared_element_icon"
)
findNavController().navigate(R.id.action_FragmentA_to_FragmentB, null, null, extras)
}
class FragmentB: Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = AutoTransition()
val transition = TransitionSet().apply {
addTransition(ChangeBounds())
addTransition(ChangeImageTransform())
}
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
}
}