El uso de animación vectorial de Android, Path.java y pathData

fondo

  • Mapa de bits: representación en píxeles de una imagen
  • Ilustración vectorial: imagen de representación de ecuación matemática Wikipedia
  • Animación vectorial: cambie continuamente los atributos (ecuaciones) de los gráficos vectoriales para formar animaciones.
  • Animación de propiedad (ValueAnimator): dentro de un tiempo específico (Time), a una tasa de cambio específica (TimeInterpolator), un "generador de valor intermedio" que devuelve continuamente un valor intermedio específico (TypeEvaluator)

lograr

  • Paso 1
创建'实现矢量动画需要的三个文件':矢量图、属性动画、助手类  
res/drawable/vector.xml  
res/animator/object_animator.xml  
res/drawable/animated_vector_drawable.xml  
  • Paso 2
    <ImageView
    android:src="@drawable/animated_vector_drawable"
    …/>
  • Paso 3
开始动画  
    mImageView.getDrawable().start();
  • Nota
 注1:助手类指 AnimatedVectorDrawable.java
     This class uses ObjectAnimator and AnimatorSet to animate the
  properties of a VectorDrawable to create an animated drawable.
 注2:Step1中的三个文件
     <!--矢量图 res/drawable/vector.xml -->
     <vector xmlns:android="http://schemas.android.com/apk/res/android"
             android:width="64dp"
             android:height="64dp"
             android:viewportWidth="64"
             android:viewportHeight="64">
         <group
             android:name="group_demo"
             android:pivotX="32"
             android:pivotY="32"
             >
             <path
                 android:name="path_demo"
                 android:pathData="M0,0 L32,32 L32,0 z"
                 android:strokeWidth="2"
                 android:strokeColor="#000000"/>
         </group>
     </vector>

     <!--属性动画 res/animator/object_animator.xml -->
     <objectAnimator
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="1000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"/>

     <!--助手类 res/drawable/animated_vector_drawable.xml -->
     <animated-vector
             xmlns:android="http://schemas.android.com/apk/res/android"
             //指定矢量图
             android:drawable="@drawable/vector">
             <target
                 //指定将要进行动画的group或path,该名称在vector.xml中定义
                 android:name="group_demo"
                 //指定动画类型
                 android:animation="@animator/object_animator"/>
     </animated-vector>
 注3:三个文件可合并写到一个文件,方式如下
     https://developer.android.google.cn/guide/topics/graphics/vector-drawable-resources

Suplemento 1: SVG y VectorDrawable

  • SVG
    可伸缩矢量图形(Scalable Vector Graphics),矢量图的一种表述形式,  
遵从XML语法,用文本格式的描述性语言来描述图像内容,文件后缀为".svg"
例如:
     test.svg
         <?xml version="1.0" standalone="no"?>
         <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
          "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
         <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
           <circle cx="100" cy="50" r="40" stroke="black"
           stroke-width="2" fill="red" />
         </svg>
  • VectorDibujable
    安卓中使用矢量图,需将"xxx.svg"转换为上文中提到的res/drawable/vector.xml
的格式(即最终的VectorDrawable.java)
    SVG图片需要UI提供,也可以手动编写一些简单的vector.xml

Suplemento 2: Elementos y atributos admitidos por VectorDrawable

  • VectorDrawable no admite todas las especificaciones SVG. Los elementos y atributos actualmente admitidos son los siguientes:
        <vector>
            android:name
            //矢量图默认宽高
            android:width
            android:height
            //画布宽高
            android:viewportWidth
            android:viewportHeight
            android:tint
            android:tintMode
            android:autoMirrored
            android:alpha
        <group>
            android:name
            android:rotation
            //旋转、缩放一组path时的中心点,相对于画布宽高
            android:pivotX
            android:pivotY
            android:scaleX
            android:scaleY
            android:translateX
            android:translateY
        <path>
            android:name
            android:pathData
            android:fillColor
            android:strokeColor
            android:strokeWidth
            android:strokeAlpha
            android:fillAlpha
            android:trimPathStart
            android:trimPathEnd
            android:trimPathOffset
            android:strokeLineCap
            android:strokeLineJoin
            android:strokeMiterLimit
            android:fillType
        <clip-path>
            android:name
            android:pathData
  • Nota
   注1:放大缩小不失真是矢量图特性,矢量图需要有固有宽高的原因:
   android/frameworks/base/libs/hwui/VectorDrawable.h中提到  
   "VectorDrawables are drawn into bitmap caches first"

   注2:其余元素、属性的说明可查看
   https://developer.android.google.cn/reference/android/graphics/drawable/VectorDrawable  
   https://www.w3.org/TR/SVG11

Suplemento 3: elemento de ruta y atributo pathData

  • Si la "ruta del elemento" se considera el objeto de Path.java en Android (al analizar vector.xml para construir el objeto)
  • Luego, los datos en la "propiedad pathData" representan el método correspondiente en Path.java (el método correspondiente se llama en función de estos datos al construir el objeto)
例如:
      自定义View时,可以通过如下操作画出一个三角形
      public class XXX extends View {
          @Override
          protected void onDraw(Canvas canvas) {
              Path path = new Path();
              path.moveTo(0, 0);
              path.lineTo(32, 32);
              path.lineTo(32, 0);
              path.close();
              canvas.drawPath(path, getPaint());
          }
      }

      vector.xml中pathData配置如下亦代表三角形
      <vector >
          <path
              android:name="path_demo"
              android:pathData="M0,0 L32,32 L32,0 z"
            />
      </vector>

      pathData中数据“对应”Path.java中相应的方法
          M对应moveTo()
          L对应lineTo()
          z对应close()
  • Nota
   注1:pathData中M,L,Z...等的语法含义
         M:move to 落笔位置
         L:line to 划线
         Z:close 闭合
         A:elliptical arc 圆弧
    详情可参阅 https://www.w3.org/TR/SVG11/paths.html
   注2:附件VectorDemo有该例

Suplemento 4: elemento de ruta y Path.java

  • Complementar los aspectos laxos de la Tercera Escuela Secundaria.
    解析vector.xml时,<path>生成的是VFullPath对象而非Path.java的实例.但二者
  最终归宿都是/android/external/skia/src/core/SkPath.cpp
    从这点看,补充三中的类比虽不严谨,但不是很过分
  • La base de "Cada destino es SkPath"
vector.xml中Path元素及pathData属性
    inflate()时
        android/frameworks/base/graphics/java/android/graphics/drawable/VectorDrawable.java
        nSetPathString(...)
        android/frameworks/base/core/jni/android_graphics_drawable_VectorDrawable.cpp
        setPathString(...)
        /android/frameworks/base/libs/hwui/VectorDrawable.h
        void setData(const Data& data)

    draw()时
        android/frameworks/base/graphics/java/android/graphics/drawable/VectorDrawable.java
        nDraw(...)
        android/frameworks/base/core/jni/android_graphics_drawable_VectorDrawable.cpp
        draw(...)
        android/frameworks/base/libs/hwui/VectorDrawable.cpp
        Tree::draw(...)
        Tree::drawStaging(...)
        Tree::updateBitmapCache(...)
        Group::draw(...)
        Path::draw(...)
        const SkPath& Path::getUpdatedPath() {
          VectorDrawableUtils::verbsToPath(&mSkPath, mProperties.getData());
          return mSkPath;
        }
Path.java及canvas.drawPath()
    构造Path时
        android/frameworks/base/graphics/java/android/graphics/Path.java
        public Path() {
              mNativePath = init1();
           }
        android/frameworks/base/core/jni/android/graphics/Path.cpp
        static jlong init1(JNIEnv* env, jobject clazz) {
            return reinterpret_cast<jlong>(new SkPath());
           }

    canvas.drawPath()时
        android/frameworks/base/graphics/java/android/graphics/Canvas.java
        public void drawPath(Path,Paint)
        android/frameworks/base/core/jni/android_graphics_Canvas.cpp
        static void drawPath(...) {
            const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
            const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
            get_canvas(canvasHandle)->drawPath(*path, *paint);
        }

Suplemento 5: Referencia y demostración

  • referencia
  1.https://zh.wikipedia.org/wiki/%E7%9F%A2%E9%87%8F%E5%9B%BE%E5%BD%A2
  2.https://zh.wikipedia.org/wiki/%E5%8F%AF%E7%B8%AE%E6%94%BE%E5%90%91%E9%87%8F%E5%9C%96%E5%BD%A2
  3.https://www.w3.org/TR/SVG11/paths.html
  4.https://developer.android.google.cn/reference/android/graphics/drawable/VectorDrawable
  5.https://developer.android.google.cn/guide/topics/graphics/drawable-animation
  6.https://developer.android.google.cn/reference/android/graphics/drawable/AnimatedVectorDrawable#OneXML
  7.https://developer.android.google.cn/studio/write/vector-asset-studio
  8.https://www.androiddesignpatterns.com/2018/11/android-studio-svg-to-vector-cli.html
  9.属性动画机制不只是针对view来设计的allows you to animate almost anything,regardless of whether it draws to the screen or not.
    https://developer.android.google.cn/guide/topics/graphics/prop-animation
  10.文中开头提到的属性动画定义、矢量动画定义源自fyang,维基中没找到相关正式定义,百度中对矢量动画的定义有些"生硬"

Supongo que te gusta

Origin blog.csdn.net/yfbdxz/article/details/84592563
Recomendado
Clasificación