Android:AnimatedVectorDrawable循环

Cal*_*cer 10 java animation android loops vector

我正在使用https://shapeshifter.design/玩AnimatedVectorDrawables .我得到的导出文件如下.我的研究告诉我,为了循环动画,我应该将android:repeatCount ="infinite"android:repeatMode ="restart"添加到objectAnimator.

将此添加到objectAnimator只会重复这些项目之一.我将如何循环整个系列的动画?我希望动画在加载和重复时开始.

动画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
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="50dp"
            android:height="50dp"
            android:viewportWidth="50"
            android:viewportHeight="50">
            <path
                android:name="_x34_"
                android:pathData="M 25 12.3 L 39.7 37.7 L 10.3 37.7 Z"
                android:fillColor="#ffffff"
                android:strokeColor="#000000"
                android:strokeWidth="1"
                android:strokeLineCap="round"
                android:strokeLineJoin="round"
                android:strokeMiterLimit="10"/>
        </vector>
    </aapt:attr>
    <target android:name="_x34_">
        <aapt:attr name="android:animation">
            <set xmlns:android="http://schemas.android.com/apk/res/android">
                <objectAnimator
                    android:propertyName="pathData"
                    android:duration="1000"
                    android:valueFrom="M 25 12.3 L 39.7 37.7 L 10.3 37.7 L 17.397 25.437 Z"
                    android:valueTo="M 10 10 L 40 10 L 40 40 L 10 40 Z"
                    android:valueType="pathType"
                    android:interpolator="@android:anim/overshoot_interpolator"/>
                <objectAnimator
                    android:propertyName="pathData"
                    android:startOffset="1000"
                    android:duration="1000"
                    android:valueFrom="M 40 10 L 25.581 10 L 10 10 L 10 40 L 25.349 40 L 40 40 L 40 10"
                    android:valueTo="M 36.3 18.7 L 25 10.4 L 13.7 18.7 L 12.8 31.5 L 25 39.6 L 37.2 31.5 L 36.3 18.7"
                    android:valueType="pathType"
                    android:interpolator="@android:interpolator/fast_out_slow_in"/>
                <objectAnimator
                    android:propertyName="pathData"
                    android:startOffset="2000"
                    android:duration="1000"
                    android:valueFrom="M 36.3 18.7 L 25 10.4 L 13.7 18.7 L 12.8 31.5 L 25 39.6 L 37.2 31.5 Z"
                    android:valueTo="M 25 10.2 L 12.2 17.6 L 12.2 32.4 L 25 39.8 L 37.8 32.4 L 37.8 17.6 Z"
                    android:valueType="pathType"
                    android:interpolator="@android:anim/overshoot_interpolator"/>
                <objectAnimator
                    android:propertyName="pathData"
                    android:startOffset="3000"
                    android:duration="1000"
                    android:valueFrom="M 31.365 13.88 L 25 10.2 L 18.268 14.092 L 12.2 17.6 L 12.2 25.465 L 12.2 32.4 L 25 39.8 L 37.8 32.4 L 37.8 25.581 L 37.8 17.6 L 31.365 13.88"
                    android:valueTo="M 33.7 13 L 25 10.2 L 16.3 13 L 10.9 20.4 L 10.9 29.6 L 16.3 37 L 25 39.8 L 33.7 37 L 39.1 29.6 L 39.1 20.4 L 33.7 13"
                    android:valueType="pathType"
                    android:interpolator="@android:anim/decelerate_interpolator"/>
                <objectAnimator
                    android:propertyName="pathData"
                    android:startOffset="4000"
                    android:duration="1000"
                    android:valueFrom="M 39.1 20.4 L 33.7 13 L 25 10.2 L 16.3 13 L 10.9 20.4 L 10.9 29.6 L 16.3 37 L 25 39.8 L 33.7 37 L 39.1 29.6 L 39.1 20.4"
                    android:valueTo="M 39.7 20 L 32.199 16.173 L 25 12.5 L 17.885 16.13 L 10.3 20 L 10 31 L 16.994 34.031 L 25 37.5 L 32.948 34.056 L 40 31 L 39.7 20"
                    android:valueType="pathType"
                    android:interpolator="@android:interpolator/fast_out_slow_in"/>
                <objectAnimator
                    android:propertyName="pathData"
                    android:startOffset="5000"
                    android:duration="1000"
                    android:valueFrom="M 10.3 20 L 25 12.5 L 39.7 20 L 40 31 L 25 37.5 L 10 31 L 10.3 20"
                    android:valueTo="M 17.995 24.403 L 25 12.3 L 32.23 24.792 L 39.7 37.7 L 25.581 37.7 L 10.3 37.7 L 17.995 24.403"
                    android:valueType="pathType"
                    android:interpolator="@android:interpolator/fast_out_slow_in"/>
            </set>
        </aapt:attr>
    </target>
</animated-vector>
Run Code Online (Sandbox Code Playgroud)

我实现动画的java代码如下:

final ImageView animationView = (ImageView) findViewById(R.id.animationView);
final AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_dice);
animationView.setImageDrawable(drawable);
drawable.start();
Run Code Online (Sandbox Code Playgroud)

小智 14

您应该使用AnimatedVectorDrawableCompat而不是AnimatedVectorDrawable来支持较低的API,然后您也可以编写该回调并在结束时启动动画.最后你的代码应该是这样的:

val animated = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_dice)
    animated?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
        override fun onAnimationEnd(drawable: Drawable?) {
            animationView.post { animated.start() }
        }

    })
    animationView.setImageDrawable(animated)
    animated?.start()
Run Code Online (Sandbox Code Playgroud)


小智 11

use property in your objectAnimator

android:repeatMode="restart"
    android:repeatCount="infinite"
Run Code Online (Sandbox Code Playgroud)

your object is like that

 <objectAnimator
    android:propertyName="pathData"
    android:duration="1000"
    android:valueFrom="path value"
    android:valueTo="some value"
    android:valueType="pathType"
    android:repeatMode="restart"
    android:repeatCount="infinite"
    android:interpolator="@android:anim/overshoot_interpolator"/>
Run Code Online (Sandbox Code Playgroud)

  • 我有大量的 &lt;objectAnimator/&gt; 是否有机会对整个 xml 文件应用重复计数和重复模式? (4认同)
  • 这应该是公认的答案。@PabloCegarra 提到的故障是由于超调插值器而发生的。如果将其替换为线性插值器,那么答案不仅比公认的更简单,而且还更平滑,因为重新启动看起来更平滑。 (2认同)

Abd*_*lah 9

您可以使用Animatable2.AnimationCallback并重新启动AnimatedVectorDrawable动画onAnimationEnd

drawable.registerAnimationCallback(new Animatable2.AnimationCallback() {
    @Override
    public void onAnimationEnd(Drawable drawable) {
        avd.start();
    }
});

drawable.start();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,它是API 23+ (2认同)
  • 我发现有必要在onAnimationEnd()中调用`animationView.post {avd.start()}`以使循环正常工作。感谢这篇文章的建议-https://medium.com/androiddevelopers/re-animation-7869722af206 (2认同)

sco*_*yab 5

使用@Feryal Sharifzadeh 很好的答案作为基础,这是一个用于设置和循环 AVD 的 Kotlin ext 函数。

internal fun ImageView.applyLoopingAnimatedVectorDrawable(@DrawableRes avdResId: Int) {
    val animated = AnimatedVectorDrawableCompat.create(context, avdResId)
    animated?.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
        override fun onAnimationEnd(drawable: Drawable?) {
            this@applyLoopingAnimatedVectorDrawable.post { animated.start() }
        }
    })
    this.setImageDrawable(animated)
    animated?.start()
}
Run Code Online (Sandbox Code Playgroud)