まったりAndroid Framework Code Reading #3に参加してAndroid 5.0から採用されたActivityTransitionのコードを読んできたので、そのまとめ。
参考プロジェクト:https://github.com/googlesamples/android-ActivitySceneTransitionBasic
以下、MainActivity -> DetailActivityに遷移の想定で書く。
MainActivity
Activity#cancelInputsAndStartExitTransition(Bundle options)
-> ActivityTransitionState#startExitOutTransition(Activity activity, Bundle options)
-> ExitTransitionCoordinator#startExit()
-> ExitTransitionCoordinator#beginTransitions()
-> TransitionManager#beginDelayedTransition(decorView, transition)
-> TransitionManager#sceneChangeRunTransition(final ViewGroup sceneRoot, final Transition transition)
-> TransitionManager.MultiListener#onPreDraw()
-> Transition#playTransition(ViewGroup sceneRoot)
DetailActivity
ResultReceiver
-> EnterTransitionCoordinator#onReceiveResult(int resultCode, Bundle resultData)
case MSG_TAKE_SHARED_ELEMENTS:
-> EnterTransitionCoordinator#onTakeSharedElements()
-> EnterTransitionCoordinator#startSharedElementTransition(Bundle sharedElementState)
-> EnterTransitionCoordinator#startEnterTransition(Transition transition)
-> TransitionManager#beginDelayedTransition(decorView, transition)
-> TransitionManager#sceneChangeRunTransition(final ViewGroup sceneRoot, final Transition transition)
-> TransitionManager.MultiListener#onPreDraw()
-> Transition#playTransition(ViewGroup sceneRoot)
-> Transition#runAnimators()
-> Transition#runAnimator(Animator animator, final ArrayMap<Animator, AnimationInfo> runningAnimators)
-> Transition#animate(Animator animator)
sharedElementsを保存して、DetailActivityで受け取れるようにするためのクラス。
sharedElementsについては、viewはView[]に、nameはString[]に保存される。
ActivityOptions#makeSceneTransitionAnimation
の中でExitTransitionCoordinator
をインスタンス化している。
このExitTransitionCoordinator
はMainActivityを離れるときのトランジションを実行するクラス。
ExitTransitionCoordinator#startExit()
:MainActivity -> DetailActivity
ExitTransitionCoordinator#startExit(int resultCode, Intent data)
:DetailActivity -> MainActivity
設定しない限りExitTransitionCoordinatorでトランジションは行われない。
windowに背景を設定してフェードインアニメーションを実行。
多分ここからsharedElementを使ったトランジションが実行されてる。 このメソッドがどこから呼ばれてるかはわからなかった。
root viewにlistenerを設定してviewを監視。
sceneRoot.addOnAttachStateChangeListener(listener);
sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener);
viewの構築完了前にリスナーをセットし、アニメーション開始メソッドを実行。
不要なAnimatorがあれば削除し、Animatorを作成。
作成されたAnimatorを実行。
ActivityTransition周りのコードを読んでみたが、関係するクラスがたくさんあり、処理が行われている箇所を特定するのが大変だった。
実際の作業としては、OpenGrokだけで該当箇所を見つけるのが厳しかったので、ASでサンプルコードを動かしてframeworkのコードにブレークポイントを張りながら処理を追いかけていった。
たまにframework内のメソッドに遷移できないことがあったので、その時はOpenGrokで検索して見ていったが、ちゃんと選択したメソッドに遷移してくれないなど不便なところもあるので慣れが必要だね。
暫定、自分の中でのベストな方法は、メソッド名やクラス名から予想を立てて、実際にブレークポイントを張ってみていく方法が良いのかなーって感じです。
frameworkのコードリーディングはかなり膨大で、なかなかとっつきにくいのでみんなで集まってやるのがよかったと思う。
また参加したい。