如何添加动态矢量图动画?

11

我正在尝试在我的Android应用程序中将矢量路径动画到不同的路径进行测试,但它没有正常工作。屏幕上没有显示任何动画,也没有显示任何动画。

我的矢量文件是:

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="8dp"
    android:height="5dp"
    android:viewportWidth="8"
    android:viewportHeight="5">
  <path
      android:name="redot"
      android:pathData="M2.5,2.5L6,2.5"
      android:strokeWidth="4"
      android:fillColor="#00000000"
      android:strokeColor="#E61B1B"
      android:fillType="evenOdd"
      android:strokeLineCap="round"/>
</vector>

我的矢量动画文件是:

    <?xml version="1.0" encoding="utf-8"?>
    <animated-vector xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        tools:targetApi="lollipop"
        android:drawable="@drawable/ic_reddot">


        <target
            android:animation="@anim/redanim"
            android:name="redot"/>

    </animated-vector>

我的动画文件位于anim文件夹中:

<?xml version="1.0" encoding="utf-8"?>

    <set xmlns:android="http://schemas.android.com/apk/res/android">

        <objectAnimator
            android:duration="10000"
            android:propertyName="pathData"
            android:valueFrom="M2.5,2.5L6,2.5"
            android:valueTo="M2.5,2.5L31,2.5"
            android:valueType="pathType" />

    </set>

最后,我的MainActivity代码如下:

    public class MainActivity extends AppCompatActivity {
    private TextView testObj;
    private ImageView reddot;
    private AnimatedVectorDrawable animation;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
      // testObj = (TextView) findViewById(R.id.testObj);
     // testObj.setVisibility(View.INVISIBLE);
    reddot = (ImageView) findViewById(R.id.reddot);

               Drawable d =  reddot.getBackground();
            if (d instanceof AnimatedVectorDrawable) {
                Log.d("testanim", "onCreate: instancefound" );
                animation = (AnimatedVectorDrawable) d;
                animation.start();
            }

        }
    }

你能分享一下错误信息吗? - Zanshin
正如我所说,没有错误信息。 - IO Devs
尝试使用 reddot.getDrawable(); - Shashank Mishra
尝试过后,返回了 null,因为 vectoranimator 文件被添加为背景到 mainactivity xml 中的 imageview。 - IO Devs
3个回答

20

使用Shape Shifter工具,然后导出由Shape Shifter生成的动态矢量可绘制文件。将此文件添加到您的drawable文件夹中,然后将其作为背景添加到要动画化的ImageView中。

我的avd_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="vector"
        android:width="80dp"
        android:height="12dp"
        android:viewportWidth="80"
        android:viewportHeight="12">
        <path
            android:name="path"
            android:pathData="M 6 6 L 74 6"
            android:strokeColor="#e61b1b"
            android:strokeWidth="12"
            android:strokeLineCap="round"
            android:fillType="evenOdd"/>
    </vector>
</aapt:attr>
<target android:name="path">
    <aapt:attr name="android:animation">
        <objectAnimator
            android:propertyName="pathData"
            android:duration="1000"
            android:valueFrom="M 6 6 L 74 6"
            android:valueTo="M 6 6 L 1 6"
            android:valueType="pathType"
            android:interpolator="@android:anim/linear_interpolator"/>
    </aapt:attr>
</target>

我的activity_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <ImageView
       android:id="@+id/object"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginStart="8dp"
       android:layout_marginTop="8dp"
       android:layout_marginEnd="8dp"
       android:layout_marginBottom="8dp"
       android:src="@drawable/avd_anim"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

最后是我的MainActivity.class

public class MainActivity extends AppCompatActivity {
private ImageView image;
private AnimatedVectorDrawable animation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = (ImageView) findViewById(R.id.object);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Drawable d = image.getDrawable();
        if (d instanceof AnimatedVectorDrawable) {
            Log.d("testanim", "onCreate: instancefound" + d.toString());
            animation = (AnimatedVectorDrawable) d;
            animation.start();
        }
    }

}

我们能否在不使用XML参数android:src的情况下设置动画? - Egor
@EgorRandomize 是的,可以使用 image.setImageResource(R.drawable.avd_anim) - Zain

1

您应该使用redot.getDrawable()而不是getBackground() 如果您在ImageView中使用app:srcCompat="@drawable/..."而不是android:src=@drawable/...,则应添加。

if (d instanceof AnimatedVectorDrawableCompat) {                        
    AnimatedVectorDrawableCompat avd = (AnimatedVectorDrawableCompat) d;       
    avd.start();                                                               
}       

回复内容存在敏感词^**$ 文件夹。


我已尝试,但仍然不起作用。在日志中显示发现动画矢量可绘制实例,但它不按照动画XML文件中指定的运行动画。 - IO Devs
在将 anim 文件夹替换为 animator 文件夹之后,Lint 显示错误:“animator 中的动画师“redanim”在基本动画师文件夹中没有声明;这可能会导致在与此限定符不匹配的配置中查询资源时崩溃。” 这是什么意思? - IO Devs
通过一些搜索,我成功解决了动画文件夹的错误,但是我仍然无法实现路径动画 :( - IO Devs
@IODevs你能发一下使用这个矢量的ImageView代码吗? - Stanislav Bondar
实际上我现在已经成功获得了动画效果,我使用了ShapeShifter工具,它自动生成了适用于我动画的矢量XML。 - IO Devs

0
补充+IO Devs的回答:
如果你想让动画无限循环播放,你应该添加AnimationCallback(抱歉,我改用Kotlin语言)
if (d is AnimatedVectorDrawable) {
    val anim = d as AnimatedVectorDrawable
    anim.start()
    anim.registerAnimationCallback(object : Animatable2.AnimationCallback() {
        override fun onAnimationEnd(drawable: Drawable?) {
            anim.start()
        }
    })
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接