初めまして、アライドアーキテクツのナムです。
現在はBRANDCoの開発を担当しております。
業務ではウェブエンジニアとして働いていますが、Androidに関しても興味を持っており、
今回はAndroidのアニメーションに関することを書いてみようと思います。
Androidアニメーションについて
Androidアニメーションと言えば3つの種類があります、ViewアニメーションとPropertyアニメーションとDrawableアニメーションです。
View Animation
3つの種類の中に一番簡単なアニメーションで、Viewsに基本的なアニメーション(alpha, translate, rotate,…)を行うことができます。
Drawable Animation
アニメーションの各フレームを定義したい時、GIFのような連続アニメーションを作りたい時、Drawable Animationをオススメです。しかし、フレームはDrawableのリソースを使うので、パラパラになって、各フレームを定義するのはかなり大変だと思います。
Property Animation
Android 3.0(API 11)からサポートされて、多く機能を持って、柔軟性が高くて、カスタマイズしやすいです。複雑なアニメーションを作るとき、Property Animationを使ったら、うまくできます。
3Dコインフリップのアニメーション
今回はPropertyアニメーションを使って、表裏回転するコインのアニメーションを一緒に作ってみましょう!!!
なぜPropertyアニメーションなのか?
View Animationだけで多く仕様を対応することができますが、基本的な機能しかサポートしないので、
3Dコインフリップなど複雑なアニメーションなら、実行することはできません。
Drawable Animationなら全然大丈夫ですが、複数のフレーム(画像)が必要になります。
実はProperty Animationに比べて、Drawble Animationを使えば、ソースコードは短く、処理は早くなり、簡単に実行することができます。
しかし、各フレームを定義することの代わりに、表と裏の2枚の画像だけで、Property Animationを使って、3Dコインフリップを作ることもできます。それはフレームを準備したくない人にとって、凄く便利ですね。
カードフリップというアニメーションのチュートリアル、以下のリンクが参考になりました。
http://developer.android.com/training/animation/cardflip.html
この資料により、フラグメントを使って、アニメーションを作りますので、画面遷移などで使ったら、すごく良いアイデアです。
今回コインを1回だけではなく、何回もぐるぐる回転するアニメーションを作ってみましょう!
まず、コインの表側と裏側のビューを定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * 表側のビュー */ <ImageView android:id="@+id/back_img_view" android:layout_width="300dp" android:layout_height="300dp" android:src="@drawable/front"/> /** * 裏側のビュー */ <ImageView android:id="@+id/front_img_view" android:layout_width="300dp" android:layout_height="300dp" android:src="@drawable/back"/> |
上書いたImageViewのsrcのfrontとbackはコインの表側と裏側の画像です。画像はなんでもいいですから、自分の画像を勝手に使ってもオーケーですよ!
次はAnimation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/** * coin_flip_left_in.xml */ <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 最初は非表示にして、alphaは0にセットします --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:duration="0"/> <!-- フリップするメインアニメーション --> <objectAnimator android:valueFrom="-180" android:valueTo="0" android:propertyName="rotationY" android:duration="@integer/full_flip_time"/> <!-- startOffsetは500から、フリップする途中で表示にして、alphaは1にセットします --> <objectAnimator android:valueFrom="0.0" android:valueTo="1.0" android:propertyName="alpha" android:startOffset="@integer/half_flip_time" android:duration="1"/> </set> |
full_flip_timeは回転速度で、ここは1000(1秒)にセットして、half_flip_timeは500(0.5秒)です。
表側を非表示するアニメーションは逆です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * coin_flip_left_out.xml */ <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- フリップするアニメーション --> <objectAnimator android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" android:duration="@integer/full_flip_time"/> <!-- フリップする途中で、非表示にセットします --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:startOffset="@integer/half_flip_time" android:duration="1"/> </set> |
アニメーションDONE!
コインの両側を表示するため、FrameLayoutを使うことになります。
FrameLayoutの中に先ほど作ったコインの両側のビューを追加します。
(また)なぜFrameLayoutを使うのか?
FrameLayoutのとても便利な特徴はビューを重ね合わせ表示できることです。
コインをフリップするとき、他の側を表示することは一番大事なことなので、FrameLayoutにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/coin_container_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" > /** * 表側のビュー */ ... /** * 裏側のビュー */ ... </FrameLayout> |
CoinFlipActivityで上のレイアウトをContentViewにセットして、それからコインの各側も定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class CoinFlipActivity extends Activity { ... /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mFrontView = (ImageView)findViewById(R.id.front_img_view); mBackView = (ImageView)findViewById(R.id.back_img_view); } } |
コインのフリップアニメーションも
1 2 3 4 5 6 |
... mAnimationLeftIn = AnimatorInflater.loadAnimator(this, R.animator.coin_flip_left_in); mAnimationLeftIn.setTarget(mBackView); mAnimationLeftOut = AnimatorInflater.loadAnimator(this, R.animator.coin_flip_left_out); mAnimationLeftOut.setTarget(mFrontView); |
OK!後はクリックイベントを取得して、コイン回転を行います。
そうすると、画面をクリックするとき、コイン回転するのを起動します。
1 2 3 4 5 6 7 8 |
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.container); mainLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mAnimationLeftIn.start(); mAnimationLeftOut.start(); } }); |
さあさあ、ビルドしてみましょう!!!
うまくフリップしますね、でも一回しか回転できない。。。
まず、アニメーションを修正して、以下のを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/** * coin_flip_left_out.xml */ ... <objectAnimator android:valueFrom="180" android:valueTo="360" android:propertyName="rotationY" android:duration="@integer/full_flip_time" android:startOffset="@integer/full_flip_time"/> // half_flip_time_2 = full_flip_time + half_flip_time <objectAnimator android:valueFrom="0.0" android:valueTo="1.0" android:propertyName="alpha" android:startOffset="@integer/half_flip_time_2" android:duration="1"/> /** * coin_flip_left_in.xml */ ... <objectAnimator android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" android:duration="@integer/full_flip_time" android:startOffset="@integer/full_flip_time"/> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:startOffset="@integer/over_flip_time" android:duration="1"/> |
あと、AnimatorListenerをimplementして、アニメーションのステータスにより、適当な動作を実行します。
今回はコインを無限にフリップするため、onAnimationEndという関数だけ使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class CoinFlipActivity extends Activity implements Animator.AnimatorListener { ... @Override public void onAnimationStart(Animator animator) {} @Override public void onAnimationEnd(Animator animator) { // 終了したanimatorを再起動する animator.start(); } @Override public void onAnimationCancel(Animator animator) {} @Override public void onAnimationRepeat(Animator animator) {} ... } |
AnimatorのListenerの設定を忘れないで
1 2 3 4 |
... mAnimationLeftIn.addListener(this); mAnimationLeftOut.addListener(this); ... |
DONE!!!
ビルドしてみましょう!結果はこういう感じになっています。
最後に
以上となります。
今回簡単で、コインの両側しか使いませんでしたが、コインのエッジも追加して、ズームなどのアニメーションも使ったら、もっと綺麗になると思います。
こんにちは!2014に新卒業でベトナムから入社しました。 よろしくお願い致します!