onDrawで描画しようかなーと思っていたけど、AnimatedVectorDrawableでいけるんじゃないかと気づいたので、お試し。
出来あがり
お悩みポイント
Shape Shifterに大量の丸をいい感じに追加したい
- 取っ掛かりとしてShape Shifterを使ったのだけど、Sketchからエクスポートした丸を複数インポートする方法がよくわからなかった
- 結果として、以下の手順を踏むことでうまくインポートできた
- Sketchでアートボードを作って、必要な数の丸を並べる
- アートボードをSVGとして、エクスポート
- このSVGをShape Shifterにインポートしても、丸が個別に認識されなかった…
- エクスポートしたSVGをAndroidStudioに取り込んで、VectorDrawableに変換
- VectorDrawableをShape Shifterにインポート
- 丸が個別に認識されるので、いい感じにアニメーションを当てれる
どうやってループさせるの?
- repeatModeみたいな設定することが出来なさげ
- 個別のobjectAnimatorには設定できるかもしれないけど(未検証)、全体のアニメーションを一纏まりとしてループしてほしい
- 実直にアニメーションの終了タイミングを捕まえて、再度startを実行した
こんな感じ
val imageView = findViewById<AppCompatImageView>(R.id.image_view)
val drawable = imageView.drawable as AnimatedVectorDrawableCompat
drawable.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
imageView.post { (drawable as AnimatedVectorDrawableCompat).start() }
}
})
drawable.start()
ちなみにXMLファイルはどうなったか
- 長くなった
- アニメーションの設定は全てをShape Shifter上で行った訳ではなくて、2個分設定してエクスポートしたものをコピペして量産した
- そこでタイミングなども調整
- こう見ると丸のpathにも当然規則性がある訳で、無理にShape Shifterに大量の丸をインポートしなくてもコピペでいけたなと…
avd_dots_anim.xml
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="dots"
android:width="64dp"
android:height="12dp"
android:viewportHeight="12"
android:viewportWidth="64">
<group android:name="dot_1">
<path
android:name="dot_path_1"
android:fillColor="#D8D8D8"
android:pathData="M 4 6 M 2 6 C 2 4.895 2.895 4 4 4 C 5.105 4 6 4.895 6 6 C 6 7.105 5.105 8 4 8 C 2.895 8 2 7.105 2 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_2">
<path
android:name="dot_path_2"
android:fillColor="#D8D8D8"
android:pathData="M 12 6 M 10 6 C 10 4.895 10.895 4 12 4 C 13.105 4 14 4.895 14 6 C 14 7.105 13.105 8 12 8 C 10.895 8 10 7.105 10 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_3">
<path
android:name="dot_path_3"
android:fillColor="#D8D8D8"
android:pathData="M 20 6 M 18 6 C 18 4.895 18.895 4 20 4 C 21.105 4 22 4.895 22 6 C 22 7.105 21.105 8 20 8 C 18.895 8 18 7.105 18 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_4">
<path
android:name="dot_path_4"
android:fillColor="#D8D8D8"
android:pathData="M 28 6 M 26 6 C 26 4.895 26.895 4 28 4 C 29.105 4 30 4.895 30 6 C 30 7.105 29.105 8 28 8 C 26.895 8 26 7.105 26 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_5">
<path
android:name="dot_path_5"
android:fillColor="#D8D8D8"
android:pathData="M 36 6 M 34 6 C 34 4.895 34.895 4 36 4 C 37.105 4 38 4.895 38 6 C 38 7.105 37.105 8 36 8 C 34.895 8 34 7.105 34 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_6">
<path
android:name="dot_path_6"
android:fillColor="#D8D8D8"
android:pathData="M 44 6 M 42 6 C 42 4.895 42.895 4 44 4 C 45.105 4 46 4.895 46 6 C 46 7.105 45.105 8 44 8 C 42.895 8 42 7.105 42 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_7">
<path
android:name="dot_path_7"
android:fillColor="#D8D8D8"
android:pathData="M 52 6 M 50 6 C 50 4.895 50.895 4 52 4 C 53.105 4 54 4.895 54 6 C 54 7.105 53.105 8 52 8 C 50.895 8 50 7.105 50 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
<group android:name="dot_8">
<path
android:name="dot_path_8"
android:fillColor="#D8D8D8"
android:pathData="M 60 6 M 58 6 C 58 4.895 58.895 4 60 4 C 61.105 4 62 4.895 62 6 C 62 7.105 61.105 8 60 8 C 58.895 8 58 7.105 58 6"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</group>
</vector>
</aapt:attr>
<target android:name="dot_1">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="100"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="350"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="850"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_2">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="200"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="450"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="950"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_3">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="300"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="550"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1050"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_4">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="400"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="650"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1150"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_5">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="500"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="750"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1250"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_6">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="600"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="850"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1350"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_7">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="700"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="950"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1450"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
<target android:name="dot_8">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="800"
android:valueFrom="0"
android:valueTo="4"
android:valueType="floatType" />
<objectAnimator
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1050"
android:valueFrom="4"
android:valueTo="-4"
android:valueType="floatType" />
<objectAnimator
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="translateY"
android:startOffset="1550"
android:valueFrom="-4"
android:valueTo="0"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>