Android:AnimatedVectorDrawable循环

时间:2017-06-23 00:08:10

标签: java android loops animation vector

我正在使用https://shapeshifter.design/使用AnimatedVectorDrawables。我得到的导出文件如下。我的研究告诉我,为了循环动画我应该添加 android:repeatCount =&#34;无限&#34; android:repeatMode =&#34;重启&#34; < / em>到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>

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

final ImageView animationView = (ImageView) findViewById(R.id.animationView);
final AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_dice);
animationView.setImageDrawable(drawable);
drawable.start();

5 个答案:

答案 0 :(得分:10)

您应该使用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()

答案 1 :(得分:7)

您可以使用Animatable2.AnimationCallback并在onAnimationEnd中再次启动AnimatedVectorDrawable动画

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>BarrelFrontend</title>
  <base href="/">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  <script src="assets/js/jquery-2.1.1.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
  <body style="background-image:url('/assets/images/cellarBackgroundImage.jpg'); background-repeat: no-repeat; background-size: cover; background-attachment: fixed; background-position: center center;">
    <app-root></app-root>
  </body>
</html>

答案 2 :(得分:3)

在objectAnimator中使用属性

android:repeatMode="restart"
    android:repeatCount="infinite"

你的对象就是那个

 <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"/>

答案 3 :(得分:0)

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

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()
}

答案 4 :(得分:-4)

有两种方法可以使用AnimatedVectorDrawable。一种是对所有XML部分使用单个文件。第二个是使用三个单独的文件 - 一个用于Vector部分,第二个用于Animator部分,第三个用于连接前两个的AnimatedVectorDrawable部分。

在我的情况下,我尝试使用单个XML文件替代方案。但我遇到了问题,而且很多时间都在进行中。所以我转移到第二个替代方案,即三个XML文件替代方案。它工作正常。下面我将解释你是如何做到的。

我非常希望提供代码。但是,由于(stackoverflow)系统尚未接受的缩进问题,我无法发布代码。

在AnimatedVectorDrawable类下,所有这三个文件的示例都在android开发者网站中给出。

我假设您想对屏幕上的两个对象进行路径变形。

对于VectorDrawable文件中每个路径元素的路径变形,将有两个pathData - 从中​​变换和变形。因此,对于VectorDrawable文件中的两个路径元素,将有4个pathData,您可以将其放在字符串文件中,其名称为my_path_from1 my_path_to1,my_path_from2和my_path_to2。

在矢量可绘制文件中,根元素是向量,您可以放置​​两个路径元素 - 一个用于屏幕上的每个对象。在这些路径元素下,您可以提供strokeWidth,strokeColor pathData和名称等属性。 。此矢量可绘制文件应放在res / drawable文件夹下。

第二个是动画文件。此文件应放在res / animator文件夹下。您可以将root元素设置为在当前情况下可以拥有一个objectAnimator元素。在此,您可以从中提供duration和pathData以及要进行变形的pathData。你在属性&#34; android:valueFrom&#34;下给出的这些和&#34;机器人:valueTo&#34; 。您可以创建两个动画文件,因为&#34;来自&#34; &#34;至&#34; pathData对于VectorDrawable文件中的两个路径元素是不同的。

在动画矢量可绘制文件中给出两个目标。在每个目标下,android:name是VectorDrawable文件中的一个路径元素的名称。在android:animation下你给出一个动画文件的名称,也就是说,你给第一个目标android:animation =&#34; @ animator / first_animator&#34;。类似于第二个。现在因为两个目标在同一个文件中,所以两个目标同时进行动画制作。两个动画都可以处理两组不同的路径数据,因为两个动画文件也不同。

在java代码中查找ViewViewById你的ImageView。如果你将它作为View膨胀,那么你必须输入它作为imageview。然后从图像视图中获取getDrawable。现在如果drawable instanceOf Animatable则drawable.start()。

希望这会对你有所帮助。

为了更好地理解这些动画,您可以参考&#34;图标动画技术简介&#34;这是

http://www.androiddesignpatterns.com/2016/11/introduction-to-icon-animation-techniques.html

希望这会对你有所帮助。