DroidKaigi 2016 @cattaka_net
用途に合わせた
アニメーションの実装方法
Takao Sumitomo
@cattaka_net
DroidKaigi 2016 @cattaka_net
自己紹介
●
住友 孝郎(Takao Sumitomo)
●
Androidアプリ開発者
●
開発経歴
●
Androidアプリ
●
iOSアプリ(ちょっとだけ)
●
業務系Webアプリケーション
●
業務系Windowsアプリ
●
その他
●
電子工作
●
OpenCV
●
ウォンテッドリー株式会社所属
2014年12月〜
DroidKaigi 2016 @cattaka_net
アプリに動きをつけていますか?
DroidKaigi 2016 @cattaka_net
必要なときにググれば
良いと思っていませんか
DroidKaigi 2016 @cattaka_net
実はアニメーションの仕組みは
AndroidのFWには沢山あります
DroidKaigi 2016 @cattaka_net
一口にアニメーションといっても
対象は何があるでしょう
●
Viewの中身を動かす
●
View自体を動かす
●
複数のViewを含むレイアウトを切り替える
DroidKaigi 2016 @cattaka_net
今のAndroidフレームワークの現状
●
それぞれに仕組みが準備されています。
●
でも新しいのや古いのやでそれぞれに複数あ
り、ややこしいことになっている
DroidKaigi 2016 @cattaka_net
今回はそれを
整理したいというお話です
DroidKaigi 2016 @cattaka_net
Viewの中身を動かす
DroidKaigi 2016 @cattaka_net
Viewの中身を動かす
●
2種類
●
Animation Drawable
●
Animated Vector Drawable
DroidKaigi 2016 @cattaka_net
Animation Drawable
●
要はパラパラアニメ
●
必要なもの:複数の画像 & xml
(1) (2)(3)
DroidKaigi 2016 @cattaka_net
Animation 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/roll_cat_1"
android:duration="200"/>
<item
android:drawable="@drawable/roll_cat_2"
android:duration="200"/>
<item
android:drawable="@drawable/roll_cat_1"
android:duration="200"/>
<item
android:drawable="@drawable/roll_cat_3"
android:duration="200"/>
</animation-list>
drawable/roll_cat.xml
DroidKaigi 2016 @cattaka_net
Animation Drawable
ImageView logoImage
= (ImageView) findViewById(R.id.image_logo);
logoImage.setBackgroundResource(R.drawable.roll_cat);
AnimationDrawable rollCatDrawable
= (AnimationDrawable) logoImage.getDrawable();
rollCatDrawable.start();
アニメーションを開始するコード
DroidKaigi 2016 @cattaka_net
Animated Vector Drawable
●
SVGをアニメーションさせる
●
必要なもの:xml
DroidKaigi 2016 @cattaka_net
Animated Vector Drawable
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<group android:name="characterGroup">
<path
android:name="character"
android:fillColor="#000000"
android:pathData="M 80,0 24,24 0,80 l 24,56 56, -省略-” />
</group>
<group android:name="feedGroup"
android:translateX="80">
<path
android:fillColor="#000000"
android:pathData="M 72,64 l -8,8 0,16 8,8 16,0 8-省略-” />
/>
</group>
</vector>
これは動きのないただのSVG
DroidKaigi 2016 @cattaka_net
Animated Vector Drawable
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vector_drawable" >
<target
android:name="feedGroup"
android:animation="@anim/av_translation" />
<target
android:name="character"
android:animation="@anim/av_path_morph" />
</animated-vector>
android:animationで動きを入れる
DroidKaigi 2016 @cattaka_net
View自体を動かす
DroidKaigi 2016 @cattaka_net
View Animation
●
必要なもの:xml & code
DroidKaigi 2016 @cattaka_net
View Animation
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:interpolator="@android:anim/bounce_interpolator"
android:toXDelta="100%"
android:toYDelta="100%"/>
Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_move);
mTargetButton.startAnimation(anim);
xmlでアニメーションを定義
コードからアニメーションを実行
DroidKaigi 2016 @cattaka_net
View Animation
TranslateAnimation anim
= new TranslateAnimation(0, mTargetView.getWidth(),
0, mTargetView.getHeight());
anim.setDuration(3000);
mTargetView.startAnimation(anim);
コードからアニメーションを実行
コードでアニメーションを定義
DroidKaigi 2016 @cattaka_net
Property Animation
●
2通りの実装がFWにある
●
ObjectAnimatorクラス
●
必要なもの:xml or code
●
リフレクションを使っていて、属性の名前でアニメーション
させる
●
ViewPropertyAnimatorクラス
●
必要なもの:code
●
codeからしか使えないが、手軽に使える
DroidKaigi 2016 @cattaka_net
ObjectAnimator
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:interpolator="@android:anim/bounce_interpolator"
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="300"
android:valueType="floatType"/>
Animator anim
= AnimatorInflater.loadAnimator(this, R.animator.pa_move);
anim.setTarget(mTargetButton);
anim.start();
このtranslationXは何処を指しているか?
xmlでアニメーションを定義
コードからアニメーションを実行
DroidKaigi 2016 @cattaka_net
ObjectAnimator
Viewクラスのメソッドを指している。
つまりリフレクションで叩いている。
DroidKaigi 2016 @cattaka_net
ObjectAnimator
ObjectAnimator animator
= ObjectAnimator.ofFloat(mTargetButton, "translationX",
0F, mTargetButton.getWidth());
animator.setDuration(3000);
animator.start();
他にも ofInt や ofObject や ofMultiFloat などがある
コードからアニメーションを実行
コードでアニメーションを定義
DroidKaigi 2016 @cattaka_net
ViewPropertyAnimator
mTargetView.animate()
.translationX(mTargetButton.getWidth())
.setDuration(3000)
.start();
mTargetView.animate()
.rotation(360f)
.setDuration(3000)
.start();
X方向に平行移動
360°回転
移動や回転以外に拡大縮小や透過も同じように書けます
DroidKaigi 2016 @cattaka_net
複数のViewを含むレイアウト
DroidKaigi 2016 @cattaka_net
名前の整理
●
Activity Animation
●
Fragment Animation
●
Transition
●
Activity Transition
●
Fragment Transition
それぞれ異なる動きをする。
(正式名称が見当たらなものは仮の名前です)
DroidKaigi 2016 @cattaka_net
Activity/Fragment Animation
DroidKaigi 2016 @cattaka_net
Activity Animation
●
必要なもの:xml & code
●
Viewを動かすのに使ったアニメーションと同
じものを使う
Intent intent = new Intent(this, At2Activity.class);
startActivity(intent);
overridePendingTransition(R.anim.aa_slide_in, R.anim.aa_slide_out);
DroidKaigi 2016 @cattaka_net
Fragment Animation
●
必要なもの:xml & code
●
Viewを動かすのに使ったアニメーションと同じもの
を使う
●
Support LibraryのFragmentかどうかによって落と
し穴がある
●
Support Libraryを使うとき
– View Animationを使う
●
Support Libraryを使わないとき
– Property Animationを使う
DroidKaigi 2016 @cattaka_net
Fragment Animation
Fragment fragment = Fa1Fragment.newInstance();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.aa_slide_in, R.anim.aa_slide_out);
ft.replace(R.id.layout_fragment, fragment);
ft.commit();
バックキーで戻る時のアニメーションを指定する
引数が4つのものも存在します。
DroidKaigi 2016 @cattaka_net
Transition
DroidKaigi 2016 @cattaka_net
3つのTransition共通の考え方
●
遷移前と遷移後のレイアウトに含まれるViewを
3つのグループに分けて考える
●
前後の画面と共通のView
●
前の画面のみのView
●
後の画面のみのView
●
これら3グループについてそれぞれ動きを指定す
る
DroidKaigi 2016 @cattaka_net
3つのTransition共通の考え方
(1)
(2)
(3)
(4)
●
前後の画面と共通のView:(1)は移動させる
●
前の画面のみのView :(2)(3)はフェードアウトさ
せる
●
後の画面のみのView :(4)はフェードインさせる
DroidKaigi 2016 @cattaka_net
Transition
●
必要なもの:xml & code
●
ViewGroupの中身を入れ替えるときに使う
●
正直ViewGroupをコードから直接追加したり除
去したり余りしないのでそもそも出番がすくな
い
DroidKaigi 2016 @cattaka_net
Transition
(1)
(2)
(3)
(4)
DroidKaigi 2016 @cattaka_net
Transition
Scene scene = Scene.getSceneForLayout(mContainerLayout,
R.layout.activity_ta_child_rb, this);
Transition transition
= TransitionInflater.from(this).inflateTransition(R.transition.ta);
TransitionManager.go(scene, transition);
対象となるViewGroup
遷移後のレイアウト
どのように遷移するか
(次ページ)実行
DroidKaigi 2016 @cattaka_net
Transition
<?xml version="1.0" encoding="utf-8"?>
<transitionSet
xmlns:android="http://schemas.android.com/apk/res/android">
<fade/>
<changeBounds>
<targets>
<target android:excludeId="@id/button_excluded"/>
</targets>
</changeBounds>
</transitionSet>
DroidKaigi 2016 @cattaka_net
指定できる動きの種類
Class Tag 動き
AutoTransition <autoTransition/> 自動
Fade <fade/> フェードイン/アウト
(オプションで指定)
ChangeBounds <changeBounds/> 移動とリサイズ
Javadocを見ると、この他にChangeClipBounds, ChangeImageTransform,
ChangeScroll, ChangeTransform, TransitionSet, Visibility, Explode, Slide
がある
DroidKaigi 2016 @cattaka_net
Activity Transition
●
必要なもの:xml or code
(1)
(2)
(3)
(4)
DroidKaigi 2016 @cattaka_net
Activity Transition
ActivityOptions options
= ActivityOptions.makeSceneTransitionAnimation(
this,
new Pair<>(view.findViewById(R.id.image_logo),
“transition:image_logo”)
);
getWindow().setSharedElementEnterTransition(new ChangeBounds());
getWindow().setSharedElementReturnTransition(new ChangeBounds());
getWindow().setEnterTransition(new Fade());
getWindow().setExitTransition(new Explode());
Intent intent = new Intent(this, At2Activity.class);
startActivity(intent, options.toBundle());
遷移の前後で共通の要素を指定
それぞれの動きを指定する
DroidKaigi 2016 @cattaka_net
Activity Transition
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/logo"
android:transitionName=“transition:image_logo”/>
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:text="Button 3"/>
</RelativeLayout>
DroidKaigi 2016 @cattaka_net
Fragment Transition
●
必要なもの:xml or code
(1)
(2)
(3)
(4)
DroidKaigi 2016 @cattaka_net
Fragment Transition
Fragment fragment = Ft2Fragment.newInstance();
fragment.setEnterTransition(new Fade(Fade.IN));
fragment.setExitTransition(new Fade(Fade.OUT));
fragment.setSharedElementEnterTransition(new ChangeBounds());
fragment.setSharedElementReturnTransition(new ChangeBounds());
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.layout_fragment, fragment);
Fragment currentFragment
= getFragmentManager().findFragmentById(R.id.layout_fragment);
ft.addSharedElement(currentFragment.getView().findViewById(R.id.image_logo),
"transition:image_logo");
ft.addSharedElement( currentFragment.getView().findViewById(R.id.button_a),
"transition:button_a");
ft.addToBackStack(null);
ft.commit();
遷移の前後で共通の要素を指定
それぞれの動きを指定する
DroidKaigi 2016 @cattaka_net
Fragment Transition
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 省略 -->
<ImageView
android:id="@+id/image_logo"
~~~~~~
android:transitionName="transition:image_logo"/>
<FrameLayout
~~~~~~
>
<Button
android:id="@+id/button_a"
~~~~~~
android:text="Button A"
android:transitionName="transition:button_a"/>
</FrameLayout>
<!-- 省略 -->
</RelativeLayout>
DroidKaigi 2016 @cattaka_net
APIレベルについて
名前 API Level
Drawable Animation 1 (Android 1.0)
Animated Vector Drawable 21 (Android 5.0)
View Animation 1 (Android 1.0)
Property Animation 11 (Android 3.0.x)
Transition 19 (Android 4.4)
Activity Transition 21 (Android 5.0)
Fragment Transition 21 (Android 5.0)
DroidKaigi 2016 @cattaka_net
APIレベルについて
●
Android 5.0で一通り揃っている
●
Transitionが比較的新しいバージョンでないと
使えない
●
Support Libraryにメソッドはあるけど肝心の
Transitionのクラスが無いので使えない
DroidKaigi 2016 @cattaka_net
まとめ
●
アニメーションの仕組みは地味に多い
●
でもそれぞれ用途が異なる
●
用途に合わせたものを使おう
●
ユーザーにわかりやすい表現をしよう
DroidKaigi 2016 @cattaka_net
サンプルアプリ
https://github.com/cattaka/LearnAnimation
ほとんどのコードのSnippetが入ってます
DroidKaigi 2016 @cattaka_net
ご清聴ありがとうございました
Takao Sumitomo
@cattaka_net

用途に合わせたアニメーションの実装方法