Androidのアニメーションを色々作ってみる
アニメーションに苦手意識があったので、アニメーションのAPIを叩いてみました。
1つ2つならコールバックでいけますが、もっとたくさんのアニメーションを逐次連続して実行したい場合などは、http://language-and-engineering.github.io/android-mvc-framework/ を見るとよいらしいです。
内容
- ViewCompatを使う
- Drawable Animationを使う
- Tween Animationを使う
ViewCompatを使う
参考:
ViewCompat | Android Developers
TextInputLayoutのソースコードを見ていたら、ViewCompatを使ってViewの透明度やサイズ等を、変更にかける時間等と合わせていじれるそうで、試してみた。
消えるとき、ちょっと上の方へ消えて欲しいとか、透明度をすいっと変化して欲しいとか、それくらいの簡単なアニメーションならこれが便利ではと思ったけど、同種のアニメーションを使い回したい場合はやっぱりTweenの方を使ってxmlのリソースを各所から呼び出す方がいいんだろうか。
1つのアニメーションするカスタムビューを作って使い回すならこれがよさそう。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/text_view" android:text="Anim by ViewCompat" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/button" android:text="push" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
public class MainActivity extends AppCompatActivity { private boolean TEXT_VISIBILITY = true; private int ANIMATION_DURATION = 1000; static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator(); private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.text_view); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TEXT_VISIBILITY) { TEXT_VISIBILITY = false; ViewCompat.animate(mTextView) .alpha(0f) // 透明度0へ向かってアニメーション .translationY(-16) // 上の方へ消えていく .scaleX(2f) // 透明になった時のサイズ .setDuration(ANIMATION_DURATION) .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR) .setListener(new ViewPropertyAnimatorListenerAdapter(){ // 設定したアニメーションが終わったら非表示に @Override public void onAnimationEnd(View view) { view.setVisibility(View.INVISIBLE); } }) .start(); } else { TEXT_VISIBILITY = true; ViewCompat.animate(mTextView) .alpha(1f) .translationY(0) .scaleX(0.5f) // 表示された時の倍率 .setDuration(ANIMATION_DURATION) .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR) .setListener(new ViewPropertyAnimatorListenerAdapter(){ // 設定したアニメーションが始まる際に表示状態に @Override public void onAnimationStart(View view) { view.setVisibility(View.VISIBLE); } }) .start(); } } }); }
Tween Animationを使う
参考:
Viewにアニメーションを付与する(Tweenアニメーション) « Tech Booster
res/animにxmlを書いてアニメーションを作るTweenアニメーション。Animation#setFillAfter(true)
でアニメーション終了後のα値や相対移動値を保持できるみたいです。
public class MainActivity extends AppCompatActivity { private boolean TEXT_VISIBILITY = true; private TextView mTextView; private Animation anim_start; private Animation anim_end; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.text_view); Button button = (Button) findViewById(R.id.button); anim_start = AnimationUtils.loadAnimation(this, R.anim.anim_start); anim_end = AnimationUtils.loadAnimation(this, R.anim.anim_end); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (TEXT_VISIBILITY) { TEXT_VISIBILITY = false; mTextView.startAnimation(anim_start); mTextView.setVisibility(View.VISIBLE); } else { TEXT_VISIBILITY = true; mTextView.startAnimation(anim_end); mTextView.setVisibility(View.INVISIBLE); } } });
<!-- anim_start --> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:interpolator="@android:anim/accelerate_interpolator"> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" /> <translate android:fromYDelta="16" android:toYDelta="0" /> </set>
<!-- anim_end --> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:interpolator="@android:anim/accelerate_interpolator"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
Drawable Animationを使う
参考:
AnimationDrawableでアニメーションを作る « Tech Booster
drawableに画像ファイルを入れてパラパラアニメを作ります。
今回は画像が無いので色違いのshape
で対応しようと思ったらできなかったので、TweenAnimation
の時のアニメのコマを切り取ってをひたすら回してみた。
animation-list
のxmlはres/anim
ではなく、res/drawable
以下に置く必要があるので注意です。
<!-- drawableフォルダに置く --> <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/anim1" android:duration="50" /> <item android:drawable="@drawable/anim2" android:duration="50" /> <item android:drawable="@drawable/anim3" android:duration="50" /> <item android:drawable="@drawable/anim4" android:duration="50" /> <item android:drawable="@drawable/anim5" android:duration="50" /> <item android:drawable="@drawable/anim6" android:duration="50" /> </animation-list>
public class MainActivity extends AppCompatActivity { private boolean TEXT_VISIBILITY = true; private TextView mTextView; private AnimationDrawable mFrameAnimation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mTextView = (TextView) findViewById(R.id.text_view); mTextView.setBackgroundResource(R.drawable.animation_list); Button button = (Button) findViewById(R.id.button); // AnimationDrawableを取得 mFrameAnimation = (AnimationDrawable) mTextView.getBackground(); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // アニメーションの開始 mFrameAnimation.start(); } }); }