在安卓上播放/暂停Youtube动画矢量图绘制

6
我可以帮您翻译成中文。下面是翻译的结果:

我正在尝试使用SVG路径和动画向量实现类似YouTube播放/暂停的动画效果。

Strings.xml

<resources>
  <string name="app_name">AnimatedSvgTest</string>

  <string name="svg_triangle">
    M0,0 L0,24 12,12 0,0
  </string>
  <string name="svg_pause">
    M0,0 L0,24 M12,0 L12,24
  </string>
</resources>

anim/path_morph.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">
  <objectAnimator
    android:duration="4000"
    android:propertyName="pathData"
    android:valueFrom="@string/svg_triangle"
    android:valueTo="@string/svg_pause"
    android:valueType="pathType" />
</set>

drawable/avd.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/ic_play_arrow_24dp">
  <target
    android:name="play"
    android:animation="@anim/path_morph" />
</animated-vector>

drawable/ic_pause_arrow.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:width="24dp"
  android:height="24dp"
  android:viewportHeight="24.0"
  android:viewportWidth="24.0">
  <path
    android:pathData="@string/svg_pause"
    android:strokeColor="#000"
    android:strokeWidth="1.0" />
</vector>

drawable/ic_play_arrow.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:width="100dp"
  android:height="100dp"
  android:viewportHeight="100.0"
  android:viewportWidth="100.0">
  <path
    android:fillColor="#FF000000"
    android:pathData="@string/svg_triangle" />
</vector>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".MainActivity">

  <ImageButton
    android:id="@+id/button"
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_centerInParent="true"
    android:src="@drawable/avd" />

</RelativeLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ImageButton button = (ImageButton) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Animatable animatable = (Animatable) button.getDrawable();
        animatable.start();
      }
    });
  }
}

但我仍然遇到了Caused by: android.view.InflateException: Binary XML file line #2 Can't morph from的崩溃:/


"M0,0 L0,24 12,12 0,0" 和 "M0,0 L0,24 M12,0 L12,24" 不兼容,根据文档:请注意,路径必须兼容于变形。更具体地说,路径应该具有完全相同的命令长度和每个命令的参数的完全相同的长度。 - pskink
那么我该如何使这些数字“可变形”? - Daniel Gomez Rico
有没有适用于Android开发者的酷炫SVG教程? - Daniel Gomez Rico
4
您可以将"M0,0 L0,24 12,12 0,0"变形为"Mx,x Lx,x x,x x,x",其中x是任何数字。 - pskink
1个回答

21
为了实现这一点,您需要使路径兼容。具体取决于您想要实际转换的外观,有多种方法可以做到这一点,您可以使用一些技巧来确保这两个可绘制对象的pathData按照相同的顺序具有相同数量和类型的命令。在这种情况下,这意味着一个三角形使用与两个矩形相同格式的路径制作。
另一个问题是,在三角形的情况下,您正在使用fillColor,因此在屏幕上看到的是您绘制的路径内部被填充的内容,但是暂停符号使用线条粗细为1.0,因此在屏幕上看到的实际上是两条粗线而不是填充的形状。
我建议您更改这样,使两者都使用fillColor而不是彩色粗线,然后使路径兼容。
以下是如何使它们兼容的示例。 当前,不兼容的路径如下:
  <string name="svg_triangle">
M0,0 L0,24 12,12 0,0
  </string>
   <string name="svg_pause">
M0,0 L0,24 M12,0 L12,24
  </string>

它们不兼容,因为它们没有相同数量的ML命令或者坐标数目不同。兼容的路径应该像这样:

  <string name="svg_triangle">
M0,0 L0,24 12,12 0,0 M12,0 L12,0 12,0 12,0
  </string>
  <string name="svg_pause">
M0,0 L0,24 1,24 1,0 M12,0 L12,24 13,24 13,0
  </string>
你应该注意到现在这些图形具有相同数量的ML命令,以及相同数量的坐标。我已经将M12,0 L12,0 12,0 12,0添加到三角形的路径中;由于所有点都位于坐标12,0上,因此此部分在屏幕上不可见且无法勾勒出形状。 对于暂停按钮,我进行了更多修改,因为以前它只是两条线,现在我已经勾勒出了形状。为了看起来正确,请更改drawable/ic_pause_arrow.xml中的<path>部分,使其使用与播放按钮相同的fillColor,如下所示:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:width="24dp"
  android:height="24dp"
  android:viewportHeight="24.0"
  android:viewportWidth="24.0">
   <path
android:fillColor="#FF000000"
android:pathData="@string/svg_pause"/>
</vector>

现在您应该拥有两个可用于形态变换的矢量图。请注意,我并没有特别尝试过这个转换,它可能不会完全符合您的要求,所以可能需要一些实验。我在我的博客上写了一篇教程,其中详细介绍了一些更复杂的示例,包括源代码以及更多有关问题和技术的背景知识。希望这能有所帮助。


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