简体   繁体   English

同时绘制矢量可绘制部分的动画

[英]Animating many parts of a vector drawable simultaneously

Using AnimatedVectorDrawables, one can apply certain animations to parts of a vectordrawable (see here ). 使用AnimatedVectorDrawables,可以将某些动画应用于vectordrawable的各个部分(请参见此处 )。 For example consider the vectordrawable, called vectordrawable.xml : 例如,考虑称为vectordrawable.xml的vectordrawable

<vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:height="64dp"
 android:width="64dp"
 android:viewportHeight="600"
 android:viewportWidth="600" >
     <path
         android:name="path"
         android:fillColor="#000000"
         android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</vector>

Which is a vectordrawable containing a single path (line). 这是一个包含单个路径(线)的vectordrawable。 The desired animation would then be in a separate file, called animator.xml , for example: 然后,所需的动画将在一个单独的文件中,该文件称为animator.xml ,例如:

<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
    android:duration="4000"
    android:propertyName="trimPathEnd"
    android:valueFrom="0"
    android:valueTo="1" />
</set>

Which would be animation showing the line being drawn. 动画将显示正在绘制的线条。 These two xml files would then feed into a third animatedvectordrawable xml file: 然后,将这两个xml文件输入到第三个animationvectordrawable xml文件中:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vectordrawable">
<target
    android:animation="@anim/animator"
    android:name="path" />

</animated-vector>

So the question is, what if your vectordrawable path contained a large number of paths, which you wanted to animate simultaneously? 所以问题是,如果您的vectordrawable路径包含大量要同时设置动画的路径,该怎么办? You could do this the long way and would have to give every path a different name, then target each and every path with the same animator in your animatedvectordrawable file. 您可以这样做很长,必须给每个路径指定不同的名称,然后在animatedvectordrawable文件中使用相同的动画制作工具来定位每个路径。 But if you've got over 20 paths, this would take a long time and be a messy solution. 但是,如果您有20条以上的路径,这将花费很长时间并且是一个麻烦的解决方案。

You do have the option of enclosing a set of paths in a group, then target a single group. 您确实可以选择将一组路径包含在一个组中,然后以单个组为目标。 But the animations for groups are different to that of paths, ie animating trimPathEnd isn't possible for a group, thus you cannot apply this animation to a group of paths. 但是,组的动画与路径的动画不同,即,无法为组设置动画trimPathEnd,因此您不能将此动画应用于一组路径。

I found a library ( here ), which introduces a new imageview-esque view, which accepts vector drawables. 我找到了一个库( 在这里 ),该库引入了一个新的imageview-esque视图,该视图接受矢量可绘制对象。 You can then extract the paths (or any part of the vector drawable) either by name, or more importantly, by index. 然后,您可以按名称或更重要的是按索引提取路径(或矢量可绘制矢量的任何部分)。 Thus this allows one to animate as many paths as you like by creating a for loop, such as 因此,这可以通过创建一个for循环来为任意数量的路径设置动画,例如

RichPathView view = findViewbyId(R.id.richpathview);
for(int i=0, i<100, i++){
    RichPath richPath = view.findRichPathByIndex(i);
                RichPathAnimator.animate(richPath)
                        .trimPathEnd(0, 1)
                        .duration(1000)
                        .start();
}

This block would "draw" the first 100 paths of a vector drawable simultaneously. 此块将同时“绘制”可绘制矢量的前100条路径。

So this allows you to animate the parts of vector drawable, without having to explicitly name and reference every single part. 因此,这使您可以对矢量可绘制部分进行动画处理,而不必显式命名和引用每个部分。

I want to suggest RichPath as well to do that but I don't recommend to call RichPathAnimator.animate() inside a long loop, you can achieve the same result in a better way, please check the 3rd step in this full example: 我也想建议RichPath这样做,但我不建议在长循环内调用RichPathAnimator.animate() ,您可以通过更好的方式实现相同的结果,请在此完整示例中检查第3步:

在此处输入图片说明

1- Normal vector_drawable.xml with 6 paths: 1-具有6条路径的普通vector_drawable.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="256dp"
    android:viewportHeight="36.0"
    android:viewportWidth="36.0"
    android:width="256dp">

  <path
      android:pathData="M19.5,6.2l1.3-1.3c0.2-0.2,0.2-0.5,0-0.7c-0.2-0.2-0.5-0.2-0.7,0l-1.5,1.5C17.9,5.2,16.9,5,16,5c-1,0-1.9,0.2-2.7,0.6l-1.5-1.5c-0.2-0.2-0.5-0.2-0.7,0c-0.2,0.2-0.2,0.5,0,0.7l1.3,1.3C11,7.3,10,9,10,11h12C22,9,21,7.2,19.5,6.2z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

  <path
      android:pathData="M13.9,8.9H13V8h0.9V8.9z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

  <path
      android:pathData="M19,8.9h-0.9V8H19V8.9z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

  <path
      android:pathData="M10,22c0,0.5,0.4,1,1,1h1v3.5c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5V23h2v3.5c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5V23h1c0.5,0,1-0.5,1-1V12H10V22z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

  <path
      android:pathData="M24.5,12c-0.8,0-1.5,0.7-1.5,1.5v7c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5v-7C26,12.7,25.3,12,24.5,12z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

  <path
      android:pathData="M7.5,12C6.7,12,6,12.7,6,13.5v7C6,21.3,6.7,22,7.5,22S9,21.3,9,20.5v-7C9,12.7,8.3,12,7.5,12z"
      android:strokeColor="#A4c639"
      android:strokeWidth="0.5"
      android:trimPathEnd="1"/>

</vector>

2- Use RichPathView in your layout insead of ImageView : 2-在ImageViewlayout使用RichPathView

<com.richpath.RichPathView
    android:id="@+id/richPathView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:vector="@drawable/vector_drawable" />

3- Animate all of your paths simultaneously. 3-同时对所有路径进行动画处理。

RichPathView pathView = findViewById(R.id.richPathView);

RichPath[] paths = new RichPath[6];

for (int i = 0; i < paths.length; i++) {
    paths[i] = pathView.findRichPathByIndex(i);
}

RichPathAnimator
    .animate(paths)
    .trimPathEnd(0, 1)
    .duration(1600)
    .start();

also, it will be cleaner if we have an API like pathView.findAllRichPaths() , I have opened an issue for that here 同样,如果我们有像pathView.findAllRichPaths()这样的API,它将变得更干净,我为此在这里打开了一个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM