尝试测试 AnimatedVectorDrawable 时出错,“无法从 x 变形为 z”

Posted

技术标签:

【中文标题】尝试测试 AnimatedVectorDrawable 时出错,“无法从 x 变形为 z”【英文标题】:Error while trying to test AnimatedVectorDrawable, "Can't morph from x to z" 【发布时间】:2015-02-21 23:27:26 【问题描述】:

我想制作一个 AnimatedVectorDrawable,这样我的 FAB 至少可以看起来像 this one 一样精彩,带有动画和其他东西。

我找到了this great tutorial,关于如何使用和实现它们等,后来我找到了a very usefull tool,用于将SVG转换为android-VectorDrawables,并转换了这两个图像: https://github.com/google/material-design-icons/blob/master/content/svg/design/ic_add_48px.svg https://github.com/google/material-design-icons/blob/master/action/svg/design/ic_done_48px.svg

现在这是我想出的 xml-“代码”:

drawable/vector_add.xml:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:
    android:
    android:viewportWidth="48"
    android:viewportHeight="48">

    <group>
        <path
            android:pathData="M0 0h48v48h-48Z" />
        <path
            android:name="add"
            android:fillColor="#ffffff"
            android:pathData="M38 26h-12v12h-4v-12h-12v-4h12v-12h4v12h12v7Z" />
    </group>
</vector>

anim/add_to_done.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M38 26h-12v12h-4v-12h-12v-4h12v-12h4v12h12v7Z"
        android:valueTo="M18 32.34l-8.34-8.34-2.83 2.83 11.17 11.17 24-24-2.83-2.83Z"
        android:valueType="pathType" />
</set>

drawable/ic_add.xml:

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

    <target
        android:name="add"
        android:animation="@anim/anim_plus_to_done" />

</animated-vector>

如果我运行这段代码,我只会得到这个错误:

Caused by: android.view.InflateException: Binary XML file line #3 Can't morph from M38 26h-12v12h-4v-12h-12v-4h12v-12h4v12h12v4Z to M18 32.34l-8.34-8.34-2.83 2.83 11.17 11.17 24-24-2.83-2.83Z
        at android.animation.AnimatorInflater.setupAnimatorForPath(AnimatorInflater.java:337)
        at android.animation.AnimatorInflater.parseAnimatorFromTypeArray(AnimatorInflater.java:283)
        at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:618)
        at android.animation.AnimatorInflater.loadObjectAnimator(AnimatorInflater.java:577)
        at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:529)
        at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:542

我的猜测是两个 svg 中的两个路径太不同了,所以 Android 无法自己处理动画,我需要为每个动画“检查点”制作几个 VectorDrawables。

...我可能完全不同意这个理论,但这是我能想到的最合乎逻辑的..

我在使用 Vectors & Illustrator 等方面没有太多经验(也没有任何经验),所以你们能提供的任何帮助将不胜感激。

祝你有美好的一天, 和圣诞快乐。

真诚地, 曼斯。

【问题讨论】:

仔细阅读developer.android.com/reference/android/graphics/drawable/… "这里是path_morph.xml,它将路径从一种形状变形为另一种形状。请注意,路径必须与变形兼容。更详细地,路径应该具有完全相同的命令长度,并且每个命令的参数长度完全相同。” @pskink 谢谢先生。虽然我一个字都不懂,但现在我明白了,我对这类事情太愚蠢了。 如果你在第一个路径中有命令“l”(行)很容易,你必须在第二个路径中也有它并且具有相同数量的参数(它们当然可以不同以制作动画发生) "+" 由两行组成,对吗? “√”或“✓”也是;) 例如:“+”是“M 2,8 14,8 M 8,2 8,14”,“✓”是“M 2,8 6,14 M 6,14 14, 4"(未在设备上测试,仅取自inkscape) 【参考方案1】:

您希望变形的 VectorDrawables 必须兼容,这意味着它们必须具有相似的复杂性;相似的命令长度和数量(pksink 提到过)。

我最终解决这个问题的方法是使用“加号”符号并在 android studio 中手动修改尺寸,直到出现类似于复选标记的东西。

加向量:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:
    android:>

    <group android:name="plus_group" android:pivotX="12" android:pivotY="12">
        <path
            android:name="plus_path"
            android:strokeColor="@android:color/white"
            android:strokeWidth="3"
            android:pathData="M12,0L12,24M0,12,L24,12" />
    </group>
</vector>

复选标记向量:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:
    android:>
    <group android:name="check_group"
        android:pivotX="12"
        android:translateX="0"
        android:pivotY="12">

        <path
            android:name="check_path"
            android:strokeColor="@android:color/white"
            android:strokeWidth="3"
            android:pathData="M20,0L06,20M0,14,L08,19" />
    </group>
</vector>

请注意,它们具有相同数量的命令。复选标记看起来并不完美,但如果将其放在浮动操作按钮中,您将无法注意到。

附加提示: 将 pathData 移动到字符串变量。这样,您的 objectAnimators 就更容易保持一致性。

【讨论】:

对于具有数十条指令的复杂形状,我们应该如何使它们兼容?是否有任何工具允许以理智的方式使 2 条路径兼容(即显示从 & 到路径并让您操作它们) 我有完美的路径。它们完全等同于 Material Design 页面中提供的图标。加路径:M12,5 L12,19 M5,12 L19,12(行程宽度= 2)。完成路径:M20.3,6.3 L8.3,18.3 M4.1,12.7 L9.7,18.3(笔画宽度=1.98,但你可以使用2)【参考方案2】:

如果您希望在任意 SVG 图像(或 VectorDrawable)之间变形,您需要对齐相应的路径以使其与变形兼容。 这是一项非常繁琐的任务,但有一个命令行工具可以为您完成这项工作:VectAling

您只需从命令行运行 VectAlign 工具并传递您的原始路径,它会自动创建“可变形”序列。

使用示例:

java -jar  vectalign.jar --start "M 10,20..." --end "M 30,30..."

输出:

--------------------
  ALIGNMENT RESULT  
-------------------- 
# new START sequence:  
M 48.0,54.0 L 31.0,42.0 L 15.0,54.0 L 21.0,35.0 L 6.0,23.0 L 25.0,23.0 L 25.0,23.0 L 25.0,23.0 L 25.0,23.0 L 32.0,4.0 L 40.0,23.0 L 58.0,23.0 L 42.0,35.0 L 48.0,54.0 

# new END sequence:  
M 48.0,54.0 L 48.0,54.0 L 48.0,54.0 L 48.0,54.0 L 31.0,54.0 L 15.0,54.0 L 10.0,35.0 L 6.0,23.0 L 25.0,10.0 L 32.0,4.0 L 40.0,10.0 L 58.0,23.0 L 54.0,35.0 L 48.0,54.0 

现在您可以在您的 Android 项目中使用这些新序列,并像往常一样使用 AnimatedVectorDrawable! 在它们之间变形!​​p>

你也可以传递SVG文件

java -jar  vectalign.jar --start image1.svg --end image2.svg

这是来自 VectAlign demo:

的样本之一

【讨论】:

对齐方式非常随机。使用这种使两条路径随机匹配的工具,两个简单 SVG 之间的过渡看起来非常错误。

以上是关于尝试测试 AnimatedVectorDrawable 时出错,“无法从 x 变形为 z”的主要内容,如果未能解决你的问题,请参考以下文章

OCUnit 应用程序测试:尝试测试 UIPageControl numberOfPages == NSArray count

尝试测试异步 Dart ajax HttpRequest 时出错

尝试与 Bamboo 一起运行时,Selenium 测试挂起

软件测试作业三 尝试使用JUnit

尝试使用 Robolectric 测试 XML 解析时出错

尝试运行 jetpack compose 仪器测试时如何克服此构建错误