NavigationとMaterialContainerTransformを使う
なんかいろいろあったのでメモ。
今回の前提
implementation "androidx.navigation:navigation-fragment-ktx:2.3.0-alpha06" implementation "androidx.navigation:navigation-ui-ktx:2.3.0-alpha06" implementation "com.google.android.material:material:1.2.0-alpha06"
今回はListからDetailに遷移するときにContainer transformを入れてみることにした。ドキュメントに沿ってMaterialContainerTransform
クラスを使って実装すれば大体のところまではできる。
引っかかったいくつかのところについてまとめておく。
遷移するときにListとDetailの表示が重なってしまう
Detail(上側)のViewがそれっぽく動いているのは見えるんだけどList(下側)も見えてしまうという感じ。背景の色を指定してやればよい。MDC初心者だったのでいっぱい調べました。
containerColor = Color.WHITE
ListからDetailはアニメーションするけど逆のときはしない
ドキュメントにはList -> Detailの実装のことしか書いていないし、これで逆向きのアニメーションもOKというようなこともそれとなく書いてある。実際にはそうなんだけど、Navigationコンポーネントと一緒に使うときには気を付けなければならない。issueにも挙がっているし一つ目のコメントに答えが書いてある。ざっくりいうと、Navigationコンポーネントで画面遷移するときに実行されるFragmentTransaction.setReorderingAllowed(true)
が原因らしい。
setReorderingAllowed(true)
は普通のshared elementアニメーションだと必要(参考: Android Developers Blog: Continuous Shared Element Transitions: RecyclerView to ViewPager )らしいのだけど、MaterialContainerTransform
では今のところ逆にうまくいかないらしい。ワークアラウンドについては次のissueが詳しい。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) postponeEnterTransition() view.doOnPreDraw { startPostponedEnterTransition() } ... }
リストの一番上のアイテムだけDetailが半分になってしまう
それっぽく動いているように見えるが、
ここまではできた pic.twitter.com/MWqiS6pRF0
— まつだあきひと (@akihito104) 2020年5月9日
先頭のアイテムだけアニメーションがおかしい。
なんで?(リストの先頭だけ横から入ってくる) pic.twitter.com/SIaUsAxFEq
— まつだあきひと (@akihito104) 2020年5月9日
横から入ってきているように見えるが、実際にはアニメーションの最中だけViewが左側にずれてしまっている。モーションパスの始点と終点が同じだと動画のようになってしまうようす。苦し紛れにモーションパスを作るPathMotionクラスを実装して渡したら何となく動いたので、今のところのワークアラウンドとしておく。
https://github.com/akihito104/nasnen/pull/1/files#diff-cbd23c4e8d257b7f5cff6fa3da5bcdf9R42-R51
こういう使い方は想定していないのだろうか。例を見るとDetail側にはToolbarもContainerの中に入っているので、ここで見たような不具合は起きなさそうではある。