androidアニメーションの置換メモ
自メモ)
とりあえず書いた版。適宜補強していく予定
思い立ったきっかけ)
- 4.1以降の端末でアニメーションがおかしくなる
- 旧形式のAnimationを使っていた
Animationクリア系の試作をしてみても改善されず
//方式1 v.clearAnimation(); //方式2 v.setImageDrawable(null); //setImageBitmap した bmp.recycle() しておくようにというサイトも有る //方式3 ani.setRepeatCount(0);
ということで古いアニメーションは動作不完全 =>3系のアニメーション使いましょう
というお話もあり バックポートライブラリ nineoldandroids を試して見ることに。。
備考)
一応
anim.cancel();
みたいな関数は用意されてるけど、Animationクラスって
普通呼び出し関数内で完結してるので
AnimationListener のコールバック関数内で書かないと使い勝手が微妙ですよね‥‥(汗
今回置換に使おうとしているFW)
- NineOldAndroids
- 制限系
- LayoutTransition はサポートしてない
旧アニメーション)
- throw Life - Androidのアニメーションいろいろ
- Android Tips(13):Androidアプリ開発におけるTweenアニメーション - MONOist(モノイスト)
- Android Tips(14):Androidアプリ開発におけるFrameアニメーション - MONOist(モノイスト)
- Androidでアニメーション | SugiBlog
3系以降のAnimation系のURLMemo)
- GPソフト Wiki - AndroidのProperty Animation
- zaki日記(2011-06-07)
- http://eclairs.blog91.fc2.com/
- android - Animate the removal of a ListView item - Stack Overflow
- Using animations in Android application - Tutorial
情報的に使えるかもしれないリンク)
x位置からアニメとか
変わったアニメーション)
事前準備)
protected int m_widthPixels=0,m_heightPixels=0; private float m_density = 0; //画面サイズの取得 WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); final DisplayMetrics displayMetrics = new DisplayMetrics(); display.getMetrics(displayMetrics); m_widthPixels = displayMetrics.widthPixels; m_heightPixels = displayMetrics.heightPixels; m_density = displayMetrics.density; //dipに変える protected int d(int px) { return (int)(px*m_density); } //dipに変える protected int d(double px) { return (int)(px*m_density); }
- SizeAnimation
- 使ったこと無い‥‥‥
- RotateAnimation
- 180 =>360 回転
旧)
RotateAnimation rotate = new RotateAnimation(180, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotate.setDuration(120); rotate.startAnimation(view);
新)
ObjectAnimator.ofFloat(view, "rotation", 180, 360).setDuration(120).start()
軸 | 属性 |
---|---|
Z軸 | rotation |
X軸 | rotationX |
Y軸 | rotationY |
という形に拡張されているようです
- TranslateAnimation
- Y軸方向に差分移動
旧)
TranslateAnimation vm = new TranslateAnimation(0, 0, 0, d(20)); vm.setDuration(500); view.startAnimation(vm); vm.setFillAfter(true); //☆の対応がわからない?
新)
ObjectAnimator.ofFloat(view, "translationY", 0, d(20)).setDuration(500).start();
☆に関して>
NineOld)
- Advanced Pre-Honeycomb Animation with NineOldAndroids - Jake Wharton
記述だと基底クラスで
setFillAfter(true); //アニメーション後、初期位置に戻らない
の記載があるので気にしないで良いよう
<本来のObjectAnimator等もそうなっているのかな?
- TranslateAnimation
- X,Y軸方向に差分移動
旧>
TranslateAnimation vm = new TranslateAnimation(0, 0, d(20), d(20)); vm.setDuration(500); view.startAnimation(vm);
新)
AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(view, "translationX",0, d(20)), ObjectAnimator.ofFloat(view, "translationY",0, d(20)) ); set.setDuration(500).start();
AnimatorSet は
状態 | 関数名 |
---|---|
一緒 | playTogether |
順番 | playSequentially |
新2)
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX", d(20)); PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationY", d(20)); ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvyY).setDuration(500).start();
座標系 | 属性 |
---|---|
相対座標X | translationX |
相対座標Y | translationY |
絶対座標X | x |
絶対座標Y | y |
- ScaleAnimation
pivotX
pivotY
は 拡大縮小の基点 らしい
旧)
int w = m_widthPixels; int h = m_heightPixels; //ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) ScaleAnimation sa = new ScaleAnimation(0.7f, 1.0f, 0.7f , 1.0f, w/2, (h-50)/2); sa.setDuration(500); sa.setFillAfter(true); view.startAnimation(sa);
新1)
AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(view, "scaleX", 0.7f, 1.0f), ObjectAnimator.ofFloat(view, "scaleY", 0.7f , 1.0f), ObjectAnimator.ofFloat(view, "pivotX", w/2 , w/2), //★ ObjectAnimator.ofFloat(view, "pivotY", (h-50)/2 , (h-50)/2), //★ ココらへん不安 ); set.setDuration(500).start();
ちなみに
ObjectAnimator.ofFloat(view, "scaleX", 0.7f, 1.0f,0.5f)
とかくと3段階変化 「0,7f=>1.0f => 0.5f」となるそうです
新2)
- Android 3での書き方
- pivotX、pivotY は対応箇所見つからず。記述なくても見た目アニメ変わらない気がするんだけど、うーん><
ViewPropertyAnimator animator = view.animate() //☆ animator.scaleX(1.0f); animator.scaleY(1.0f); animator.setDuration(500).start();
ただし
- NineOldAndroid の場合
//need import static com.nineoldandroids.view.ViewPropertyAnimator.animate; ? ViewPropertyAnimator animator = animate(view); //<= view.animate()
という記述になります
- AlphaAnimation
- 徐々に透明になっていく記述
旧)
AlphaAnimation a = new AlphaAnimation(1.0f, 0.0f); a.setFillAfter(true); a.setDuration(1000); view.startAnimation(a);
新)
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.0f); animator.setDuration(1000).start();
新2)
ViewPropertyAnimator animator = animate(view); animator.alpha(0).setDuration(1000).start();
- アニメーションデータの読み込み
旧)
アニメデータは res/anim>
Animation animeJ = AnimationUtils.loadAnimation(this, R.anim.out_to_left);
view.setAnimation(animeJ);
view.startAnimation(animeJ);
- res/anim/out_to_left.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:fromXDelta="0%" android:toXDelta="500%" android:fillAfter="true" android:fillEnabled="true" android:duration="2000"/> </set>
set .. AnimationSet に対応
参考URL)
- Activityにアニメーションを付与する(TranslateAnimation) « Tech Booster
- Androidアプリのアニメーションリソースの使い方、定義方法 | mucchinのAndroid戦記
- Androidのアニメーション - fkm 〜 Super Software Entertainerへの道 〜
特に最後のリンクの
みたいな表記ができるってのは知らなかったorz。すごく勉強になるな。。
自分自身のサイズの場合は, 10%
親Viewのサイズの場合は, 10%p
新)
アニメデータは res/animator>
View viewBall = findViewById(R.id.ball);
Animator animeJ = AnimatorInflater.loadAnimator(this.R.animator.out_to_left);
animeJ.setTarget(viewBall);
animeJ.start();
公式との違いは import文くらいのところかも‥‥
import android.animation.AnimatorInflater.loadAnimator; //=> import com.nineoldandroids.animation.AnimatorInflater.loadAnimator;
<?xml version="1.0" encoding="utf-8"?> <set android:ordering="together"> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:valueType="floatType" android:propertyName="alpha" android:valueFrom="0" android:valueTo="500" android:duration="2000" /> </set>
set .. AnimatorSet に対応
objectAnimatorの記載に関しては従来通りでOK。
<?xml version="1.0" encoding="utf-8"?> <set android:interpolator="@android:interpolator/decelerate_cubic" android:ordering="together"> </set>
のように android:interpolator の設定も可能
参考URL)
Android UI ICS本には 4系だとloadAnimatorが上手く動かない的な記載があるのですけど
NineOldAndroidだと動くのか、通常のでも4.1以上では動くのか
そこら辺は未検証・・
- アニメーションのセット再生
旧)
int w = m_widthPixels; final AnimationSet as = new AnimationSet(true); //x方向に移動 TranslateAnimation hm = new TranslateAnimation(0, w, d(20), d(20)); hm.setDuration(600); AlphaAnimation a = new AlphaAnimation(1.0f, 0.0f); a.setDuration(600); as.addAnimation(hm); as.addAnimation(a); as.setFillAfter(true); as.startAnimation(view);
新)
AnimatorSet set = new AnimatorSet(); AnimatorSet as1 = new AnimatorSet(); as1 .playTogether( ObjectAnimator.ofFloat(view, "translationX", 0, w), ObjectAnimator.ofFloat(view, "translationY", d(20), d(20)) ); as1.setDuration(600); /* 一応 as1 .playTogether( ObjectAnimator.ofFloat(view, "translationX", 0, w).setDuration(600), ObjectAnimator.ofFloat(view, "translationY", d(20), d(20)).setDuration(600) ); な書き方もかけますが再生時間が違う場合でない限りあまり意味が無いような(汗 */ AnimatorSet as2 = new AnimatorSet(); Builder builder =as2.play( ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.0f) ); // builder は before/after/with という形で使う // 上記の例の場合は playTogether でもOK as2.setDuration(600); /* もしくは ObjectAnimator as2 = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.0f).setDuration(600); */ //a1 => a2 の順 set.playSequentially(as1,as2); set.start();
- playSequentially / playTogeter は AnimatorSet/ObjectAnimator/ValueAnimator等 引数に混ぜてもOKなので凄い楽。
- アニメーションリスナー
旧)
RotateAnimation setAnimationListener( new AnimationListener() { @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { } });
新)
ObjectAnimator animator animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { } }); ValueAnimator animator animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { } }); AnimatorSet as = new AnimatorSet(); as.addListener(new AnimatorListener(){ @Override public void onAnimationCancel(Animator arg0) { } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationStart(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { } });
アニメーションのパターンを指定)
旧)
Interpolator系
Animation anim = new AlphaAnimation(1, 0); anim.setDuration(500); anim.setInterpolator(new CycleInterpolator(3));//繰り返し3指定 v.startAnimation(anim);
新
ObjectAnimator obj = ObjectAnimator.ofFloat(v, "alpha", 1, 0).setDuration(500); obj.setInterpolator(new CycleInterpolator(3));//繰り返し3指定 obj.start();
参考)
Androidで動く携帯Javaアプリ作成入門(20):Androidアプリで“アニメーション”するための基礎知識 (3/3) - @IT
Androidのあ~ん |Animation その5 アニメーション分割処理パターン
Interpolatorの数値のみ利用をする。 - 素人のアンドロイドアプリ開発日記
使うとしたら、
数値加算アニメーションとかで使うのかな?
新)
TypeEvaluator系
ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE); colorAnim.setDuration(3000); colorAnim.setEvaluator(new ArgbEvaluator()); //◎ colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.start();
フラグ値 | 説明 |
---|---|
ValueAnimator.INFINITE | 無限(回数)再生 |
ValueAnimator.REVERSE | 逆再生 |
ValueAnimator.RESTART | 再生終了後、最初から |
ArgbEvaluator はRGBの変位計算するアニメパターン
IOSのような3D回転アニメ系)
Activityでやると、低端末では重いので
ViewFlipperで頑張ろうとしたが、下記みたいな感じ
ViewFlipper void setInAnimation(Animation inAnimation) AdapterViewFlipper(v11) void setInAnimation(ObjectAnimator inAnimation) v4にも無
Listener自体は下記の方法で設定可能とのこと
viewFlipper.getInAnimation().setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) {} public void onAnimationRepeat(Animation animation) {} public void onAnimationEnd(Animation animation) {} });
viewFlipper & アニメ遷移の情報は)
- ViewFlipper によるアニメーション付き画面切り替え - Android 開発入門
- チラシの裏的備忘録: ViewFlipperでページめくり ~ページ作成編
- チラシの裏的備忘録: ViewFlipperでページめくり ~動作編
- チラシの裏的備忘録: ViewFlipperでページめくり ~おまけ編
その他の回転アニメメモは)
A)縦回転>
B)横回転>
今回はまずA)で試す。
ただ横画面でこれを指定すると左右回転になってしまう・・・ ということで別途似たの作るイメージ
指定は)
int mode =0; viewFlipper.setInAnimation(AnimationUtils.loadAnimation(game_main.instance, R.anim.down_land_in)); viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(game_main.instance, R.anim.down_land_out)); viewFlipper.setDisplayedChild(mode); //ちゃんと変わっていることを確認するなら setDisplayedChild前後で viewFlipper.getDisplayedChild()で確認
縦版>
- down_in.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:startOffset="200" android:duration="200" android:fromXScale="1.0" android:toXScale="0.0" android:fromYScale="1.0" android:toYScale="0.9" android:pivotX="50%" android:pivotY="50%" />
- down_out.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="200" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.9" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" />
- up_in.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:startOffset="200" android:duration="200" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.9" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" />
- up_out.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="200" android:fromXScale="1.0" android:toXScale="0.0" android:fromYScale="1.0" android:toYScale="0.9" android:pivotX="50%" android:pivotY="50%" />
横板>
- down_land_in.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:startOffset="200" android:duration="200" android:fromYScale="1.0" android:toYScale="0.0" android:fromXScale="1.0" android:toXScale="0.9" android:pivotX="50%" android:pivotY="50%" />
- down_land_out.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="200" android:fromYScale="0.0" android:toYScale="1.0" android:fromXScale="0.9" android:toXScale="1.0" android:pivotX="50%" android:pivotY="50%" />
- up_land_in.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:startOffset="200" android:duration="200" android:fromYScale="0.0" android:toYScale="1.0" android:fromXScale="0.9" android:toXScale="1.0" android:pivotX="50%" android:pivotY="50%" />
- up_land_out.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="200" android:fromYScale="1.0" android:toYScale="0.0" android:fromXScale="1.0" android:toXScale="0.9" android:pivotX="50%" android:pivotY="50%" />
備考)ViewFlipper挙動メモ)
- layout-land にレイアウト置いてると読込エラーになるよ?
参考図書>

- 作者: 宮嵜淳,あんざいゆき,新井俊弘,坂下賢司,山田達司,市原尚久,飯塚智,安藤幸央,谷口岳,安達正,宮田義之,平和樹,坂下秀彦
- 出版社/メーカー: リックテレコム
- 発売日: 2012/08/07
- メディア: 単行本(ソフトカバー)
- 購入: 1人 クリック: 11回
- この商品を含むブログ (5件) を見る

Android UI Cookbook for 4.0 ICS(Ice Cream Sandwich)アプリ開発術
- 作者: あんざいゆき
- 出版社/メーカー: インプレスジャパン
- 発売日: 2012/03/16
- メディア: 単行本(ソフトカバー)
- 購入: 2人 クリック: 47回
- この商品を含むブログ (18件) を見る

Androidタブレットアプリ開発ガイド Android SDK 3対応 (Smart Mobile Developer)
- 作者: 井形圭介,上中正統,尾古豊明,加藤勝也,小林慎治,瀬戸健二,高木基成,日高正博,夜子まま
- 出版社/メーカー: 翔泳社
- 発売日: 2011/09/16
- メディア: 大型本
- 購入: 4人 クリック: 156回
- この商品を含むブログ (7件) を見る
TL上のメモ:NineOldAndroid)
AnimatorListenerのonAnimationEnd()の中で、位置戻しのためanimate()したらonAnimationEnd()の無限ループになってハマった。。
メモった。 ネタ帳 A.B.C: NineOldAndroidsを使ってみた URL
eclipseの保管の設定は特に参考になる
[Java] - [Editor] - [Content Assist] - [Favorites]の[New Type...]
あたりを確かに設定すると楽かも
com.nineoldandroids.animation.Animator
com.nineoldandroids.animation.Animator.AnimatorListener
com.nineoldandroids.animation.AnimatorSet
com.nineoldandroids.animation.ObjectAnimator
com.nineoldandroids.view.ViewPropertyAnimator
TL上のメモ)
有名な開発者の さんでも悩まれているみたいで
アニメーション効果って皆さん悩まれているみたいだな。。*1 *2
[http://twitter.com/kimukou2628/status/299177170222325762:twitter:tree]
@tamacjp さんのgifアニメーションの話は
- いまさらブログ: AndroidでアニメGIF表示
- ちなみにソースは下記の場所に移ってます*3
- GitHub - tamacjp/android-animatedGIF
追記)
TLメモのやつは
- xmlに複数の画像を配列で定義してランダムに表示させる - Androidはワンツーパンチ 三歩進んで二歩下がる
- AnimationDrawableでアニメーションを作る « Tech Booster
の話を組み合わせれば、わざわざImageViewオーバライドしてやる必要ないですね(汗。
public class HogeImage extends ImageView { private Bitmap image @Override protected void onDraw(Canvas c) { super.onDraw(c); //〜 中略〜 c.drawBitmap(image, 0, 0, null); } }
なイメージを想定していました。
勿論
のような Canvas.save()/Canvas.restore() が必要なレベルのアニメだとこっちのほうが楽かもしれない
あとは ValueAnimator使うとか・・(下記みたいなイメージ)。
ValueAnimator animator = ValueAnimator.ofFloat(0,5); animator.setDuration(5000); animator.addUpdateListner(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //アニメーション経過時間(ミリ秒) long currentPlayTime( = animation.getCurrentPlayTime(); //アニメーション経過割合(0-1.0) float animatatedFraction = animation.getAnimatatedFraction); //アニメーション値 float animatatedValue = animation.getAnimatatedValue(); //実際のアニメーション処理 } }); animator.start();
追記2)
IOS7の縦Swipeの要望があって調べてたら出てきたメモ
iOS8がでたらまた違う要望が出てくるんだろうなー(遠い目