STORES Product Blog

こだわりを持ったお商売を支える「STORES」のテクノロジー部門のメンバーによるブログです。

Androidでクロスフェードアニメーションを実装する

こんにちは。 STORES 決済 でAndroidアプリエンジニアをしている Yamaton です。 AndroidでViewをアニメーションさせようとしたとき、アニメーションの動きは想像できるのに、それをコードで表そうとすると案外むずかしかったりします。この記事では、クロスフェードアニメーションを実装したときにつまずいた点をあげつつ、その実装方法について共有します。

クロスフェードアニメーション

重なった2つのViewを前面のViewはフェードアウト、背面のViewはフェードインさせて入れ替えるのがクロスフェードアニメーションです。

クロスフェードアニメーションするアイコン

つまづいたところ

当初はこのように考えて実装しようとしていました。

Viewの重なり想定

  • クロスフェードするViewをA、Bとする
    • 初期表示時、前面にあるのをA、背面にあるのをBとする
      • Aのelevationを1、Bのelevationを0としておく
    • Aをフェードアウトアニメーションし、終わったら
      • Aのelevationを0、Bのelevationを1にする

→Bが前面、Aが背面になる

想定していた重なりの入れ替わり

「Viewが重なっている」ということを意識しすぎて、elevationで重なりを調整していました。が、これは不要でした。

どうしたか

普段の実装で、単純に2つのViewを切り替える場合、VISIBLE / GONEを入れ替えるだけで実現しています。 クロスフェードアニメーションは、この入れ替えの間にフェードイン、フェードアウトを追加することで実現できることに思い至りました。

ということで、コード例です。

実際には、とあるイベントを監視して、イベント発生ごとにAとBを入れ替えるような実装をしました。ここではサンプルとして2つのViewを渡して1つ目をフェードイン、2つ目をフェードアウトさせるメソッドとして抽出しました。

サンプルアプリ

おわりに

Androidクロスフェードアニメーションの実装方法の一例でした。

当初は Listener を駆使してアニメーションが終わるたびにelevationを操作していました。なんとなく無駄に複雑になっているなと思いつつ、実装を保存して一晩寝かせたところで前述の結果に思い至りました。ささいな違和感を持ったら、一度引いてながめてみるのもときには大事ですね。