天天看點

vector drawable

AnimatedVectorDrawable
  • vector drawable 類似于網頁設計的SVG是一種可縮放的矢量圖,要是能用的話盡量用這種格式的圖檔,特别是一些圖示。例如:
<?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="120dp"
        android:height="120dp"
        android:viewportWidth="24"
        android:viewportHeight="24">

        <path
            android:name="cross"
            android:pathData="M6.4,6.4,L17.6,17.6,M6.4,17.6,L17.6,6.4"
            android:strokeWidth="6"
            android:strokeLineCap="square"
            android:strokeColor="#999"/>

    </vector>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

vector drawable 形狀由pathData決定,修改pathData就能修改vector drawable的形狀。 

VectorDrawable官方文檔 

關于vector drawable的相容和一些問題,推薦看Android Vector曲折的相容之路這篇部落格。 

VectorDrawable 的标簽中有幾個很重要:

<!-- group 标簽作用
        1. 對path或者子group進行分組,便與管理各個相關的group或者path
        2. 對path進行動畫擴充,path 中的動畫沒有scale, rotate, translate
    -->
    <group
        android:name="group_c"        //名稱,AnimatedVectorDrawable 的<target>通過 android:name識别
        android:translateX="1"       // x方向平移多少
        android:translateY="2"       // y方向平移多少
        android:scaleX="1"           // x 方向放大多少
        android:scaleY="2"           // y 方向放大多少 
        android:rotation="90"        // 旋轉的角度
        android:pivotX="12"          // scale和rotation變化的中心點x坐标
        android:pivotY="12">         // scale和rotation變化的中心點y坐标
        <path
            android:name="cross"      // 名稱,AnimatedVectorDrawable 的<target>通過android:name識别 
            android:pathData="M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4 M6.4,6.4"
            android:strokeColor="#090909"      // 線條的顔色
            android:fillColor="#c0c0c0"        // 填充顔色
            android:trimPathEnd="0.9"          // 進行裁剪的結束位置,值為0~1,0為頭,1為尾
            android:trimPathStart="0.5"/>      // 進行裁剪的開始位置,值為0~1,0為頭,1為尾
    </group>           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

關于path中的pathData,參照SVG中定義的path标簽的中的指令的定義。 

Path中的指令詳解

  1. 指令 
    • M = moveto (M X,Y) : 将畫筆移動到指定的坐标位置
    • L = lineto (L X, Y) : 畫直線到指定的坐标位置
    • H = horizontal lineto (H X) : 畫水準線到指定的坐标
    • V = vertical lineto (V Y) : 畫垂直線到指定的坐标
    • C = curveto (C X1, Y1, X2, Y2, ENDX, ENDY) : 三次貝塞爾曲線
    • S = smooth curveto (S X2, Y2, ENDX, ENDY)
    • Q = quadratic Belzier curveto (Q X, Y, ENDX, ENDY) : 二次貝塞爾曲線
    • T = smooth quadratic Belzier curveto (T ENDX, ENDY) : 映射
    • A = elliptical Arc(A RX,RY,XROTATION,FLAG_LARGE, FLAG_SWEEP, X, Y) :畫弧線。
    • Z = closepath (z) : 關閉路徑。
  2. 使用的原則 
    • 坐标軸為(0,0)為中心,X軸水準向右,Y軸水準
    • 所有指令大小寫區分,大寫采用絕對定位,參照全局的坐标系,小寫采用相對定位,參照父坐标系(上一次繪制停留的那個位置)
    • 指令和資料之間的空格可以省略
    • 同一指令出現多次可以隻用一個。

對vector drawable 進行動畫,可以進行下面這些動畫,最重要的是最後三點:

  • translate 平移
  • scale 縮放
  • rotate 旋轉
  • opacity 透明度修改
  • color 色彩修改 (android:stokeColor ,android:fillColor)
  • path 路徑改變
  • trim start/end (android:trimPathStart / android:trimPathEnd)路徑剪裁
  • clip-path 剪切路徑

vector drawable的原理也隻是使用屬性動畫,檢視其源碼,上述的屬性都能找到對應的setter和getter函數,所有能進行這些動畫。

  1. 路徑變化動畫 : 例如我們将一個符号”√”變換成一個”x”符号。
    • 建立兩個vector drawable
      <!-- res/drawable/tick_drawable.xml-->
          <vector xmlns:android="http://schemas.android.com/apk/res/android"
                       android:width="24dp"
                       android:height="24dp"
                       android:viewportWith="24"
                       android:viewportHeight="24">
                       <group
                           android:name="group_tick"
                           android:pivotX="12"
                           android:pivotY="12">
                           <path 
                               android:name="tick"
                               android:stokeWidth="2"
                               android:stokeColor="$c2c2c2"
                               android:pathData="@string/path_tick"/>
                      </group>         
              </vector>   
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      <!--res/drawable/cross_drawable.xml-->
          <vector xmlns:android="http://schemas.android.com/apk/res/android"
                      android:width="24dp"
                      android:height="24dp"
                      android:viewportWith="12"
                      android:viewportHeight="12">
                      <group 
                          android:name="group_cross"
                          android:pivotX="12"
                          android:pivotY="12">
                          <path
                              android:name="corss"
                              android:strokeWidth="2"
                              android:strokeHeight="2"
                              android:strokeColor="#c2c2c2"
                              android:pathData="@string/path_cross"/>
                      </group>
              </vector>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      <!-- 分别存儲cross和tick的pathData-->
          <string name="path_cross">M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4</string>
          <string name="path_tick>M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7</string>           
      • 1
      • 2
      • 3
    • 建立屬性動畫
      <!--res/animator/cross_to_tick.xml-->
          <objectAnimator 
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:propertyName="pathData"
              android:fromValue="@string/path_cross"
              android:toValue="@string/path_tick"
              android:duration="1000"
              android:interpolator="@android:interpolator/fast_out_slow_in"
              android:valueType="pathType"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      <!--res/animator/tick_to_cross.xml-->
      <objectAnimator
         xmlns:android="http://chemas.android.com/apk/res/android"
         android:propertyName="pathData"
         android:fromValue="@string/path_tick"
         android:toValue="@string/path_cross"
         android:duration="1000"
         android:interpolator="@android:interpolator/fast_out_slow_in"
         android:valueType="pathType">              
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      <!--res/animator/rotate_tick_to_cross.xml-->
      <objectAnimator
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:propertyName="rotation"
         android:formValue="0"
         android:toValue="180"
         android:duration="1000"
         android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      <!--res/animator/rotate_cross_to_tick.xml-->
      <objectAnimator
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:propertyName="rotation"
         android:formValue="-180"
         android:toValue="0"
         android:duration="1000"
         android:valueType="floatType"
         android:interpolator="@android:interpolator/fast_out_slow_in"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 建立AnimatedVectorDrawable
      <!-- res/drawable/avd_cross_to_tick.xml 從叉到勾的路徑變化-->
          <animated-vector
                  xmlns:android="http://schemas.android.com/apk/res/android"
                  android:drawable="@drawable/cross_drawable">
                  <target
                      android:name="cross"
                      android:animation="@animator/cross_to_tick"/>
                  <target
                      android:name="group_cross"
                      android:animation="@animator/rotate_cross_to_tick"/>
      
          </animated-vector>                     
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      <!-- res/drawable/avd_tick_to_cross.xml 從勾到叉的路徑變化-->
          <animated-vector
                  xmlns:android="http://schemas.android.com/apk/res/android"
                  android:drawable="@drawable/tick_drawable">
                  <target
                      android:name="cross"
                      android:animation="@animator/tick_to_cross"/>
                  <target
                      android:name="group_cross"
                      android:animation="@animator/rotate_tick_to_cross"/>
      
          </animated-vector>                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 使用AnimatedVectorDrawable 
      ImageView imgView = (ImageView)findViewById(R.id.my_img);
      AnimatedVectorDrawable avd = (AnimatedVectorDrawable)getDrawable(R.drawable.avd_tick_to_cross);
      ...
      // 觸發動畫,例如點選某個view後觸發這個動畫
      @Overrid
      public void onClick(View v){
          img.setImageDrawable(avd);
          avd.start();
      }           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    注意:要想對pathData進行改變,這個兩個pathData中的指令必須是一樣的,隻是參數不一樣而已,否則會報錯誤的。 

    cross為: M 6.4,6.4 L 17.6,17.6 M 6.4,17.6 L 17.6,6.4 

    tick   為:M 4.8,13.4 L 9,17.6 M 10.4,16.2 L 19.6,7 

    兩者都分别采用了:M, L, M,L 四個指令,隻是參數不一樣而已,故兩者之間可以進行改變。

  2. path 繪制動态效果,例如顯示”Android Design“這兩個單詞使其看起來像在書寫出來一樣。這裡使用到的關鍵點就是path的android:trimPathEnd屬性。
    • 将”Android Design”拆成多個路徑再定義vector drawable
      <!--res/drawable/android_design.xml-->
      <vector
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:with="308dp"
       android:heigh="68dp"
       android:viewportWidth="308"
       android:viewpoerHeigh="69">
       <path
           andorid:name="andro"
           android:strokeWidth="3"
           android:strokeLineCap="round"
           android:strokeLineJoin="round"
           android:strokeColor="#fc1418"
           android:trimPathEnd="0"
           android:pathData="M0.341920533,40.5760313 C10.4153396,48.6685632 17.8034264,14.3620789 25.1846643,3.56823233 C22.6808659,17.4367383 24.2427442,35.0729292 30.8190658,37.8244796 C37.3953873,40.57603 41.5672433,24.9138787 44.6864294,17.4367377 C44.6864297,24.9138787 37.5249051,37.3372753 39.249546,38.3131369 C42.8471123,31.0871747 50.0182725,22.9181478 52.3256959,21.7592998 C54.6331193,20.6004517 50.8848435,36.4943726 53.2676171,36.1358718 C62.1953141,39.082309 62.1473214,16.7555802 74.563028,23.7653072 C62.1473214,18.8909047 62.0474335,34.9249451 63.0693063,36.4087435 C76.0701005,34.9249451 85.9997193,6.61579217 81.6328141,0.899274471 C72.6738297,-0.871651751 72.1813599,37.3152891 76.0701025,38.1418785 C86.6180283,37.824479 90.9662415,19.7790174 89.21512,15.293806 C83.852121,23.0597104 91.383788,21.276977 93.8478663,24.9138796 C96.3540742,28.3130578 90.4737717,39.4542398 96.3540742,38.8211488 C101.209825,37.9762811 111.517305,15.6548547 113.471544,21.0005578 C107.744981,18.6286267 102.662668,37.2240495 109.328684,37.824479 C117.918245,38.1418771 118.454797,21.0005578 113.471544,20.4832582"/>
      <path
          android:name="id"
          android:strokeWidth="3"
          android:strokeLineCap="round"
          android:strokeLineJoin="bevel"
          android:strokeColor="#fc1418"
          android:trimPathEnd="1"
          android:pathData="M126.046387,22.4013672 C121.762207,28.8041992 123.087402,37.2265625 125.954102,38.3725586 C130.26416,41.6142578 138.382324,19.9448242 144.455078,21.7612305 C131.391113,27.4980469 135.289551,36.3017578 137.201172,36.3017578 C152.215819,34.4545898 159.176759,1.63085934 155.48291,0.109375 C146.004882,5.33300781 145.556151,36.3017578 150.474609,38.1679688 C157.431153,38.1679688 160.515137,28.8041992 160.515137,28.8041992" />
      
      <path
          android:name="a_stroke"
          android:strokeWidth="5"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#2c6481"
          android:trimPathEnd="1"
          android:pathData="M15.5131836,25.2182617 C19.5947266,25.2182617 31.4887695,22.9897461 31.4887695,22.9897461" />
      
      <path
          android:name="i_dot"
          android:strokeWidth="6"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#ff00ff"
          android:trimPathEnd="1"
          android:pathData="M127.723145,15.8867188 L127.163086,17.0029297" />
      
      <path
          android:name="d"
          android:strokeWidth="6"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#2c6481"
          android:trimPathEnd="1"
          android:pathData="M179.80127,2.60498047 C176.131917,10.1152344 174.223633,34.0673828 173.55957,38.5478516 C175.206055,36.9267578 174.533691,36.8710938 175.60498,36.8710938 C212.008789,26.9985352 192.196777,-0.39453125 172.428711,6.56152344" />
      
      <path
          android:name="esig"
          android:strokeWidth="3"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#2c6481"
          android:trimPathEnd="1"
          android:pathData="M204.027344,29.0200195 C212.498535,24.2231445 209.48584,20.0551758 208.53125,20.0551758 C205.774902,18.3828125 196.044922,32.4404297 204.596191,37.5283203 C214.817871,41.4614258 218.684081,16.0166016 223.237792,16.0166016 C217.423339,27.6240234 235.10498,37.5283203 215.530274,38.2475586 C230.764648,44.2109375 235.949706,24.9003906 237.895507,23.5888672 C234.370117,35.1958008 236.134765,37.5283203 238.70166,38.2475586 C243.201171,39.519043 251.621093,13.8134766 264.673828,20.8544922 C251.621093,13.8134766 244.347656,35.7421875 249.693848,35.7421875 C255.04004,35.7421875 259.597167,24.2231445 262.54248,24.2231445 C262.54248,35.0126419 259.476562,60.7124023 249.032714,52.6586914" />
      
      <path
          android:name="n"
          android:strokeWidth="3"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#2c6481"
          android:trimPathEnd="1"
          android:pathData="M274.092285,17.934082 C271.665527,21.6083984 270.089844,38.465332 270.089844,38.465332 C275.562012,24.7871094 280.663086,22.0395508 282.294434,22.5825195 C283.466797,28.0629883 281.084961,34.3491211 283.559082,36.1098633 C286.033203,37.8706055 289.920898,35.0537109 293.011719,28.9052734" />
      
      <path
          android:name="second_i_dot"
          android:strokeWidth="3"
          android:strokeLineCap="round"
          android:strokeLineJoin="round"
          android:strokeColor="#2c6481"
          android:trimPathEnd="1"
          android:pathData="M239.723145,15.8867188 L239.163086,17.0029297" />
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
    • 定義每個path所需要用到的動畫
      <!--res/animator/andro.xml-->
       <objectAnimator
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:propertyName="trimPathEnd"
           android:valueFrom="0"
           android:valueTo="1"
           android:duration="1000"
           android:interpolator="@android:interpolator/fase_out_slow_in"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      <!--res/animator/id.xml-->
      <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="1050"
          android:duration="250"
          android:interpolator="@android:interpolator/fast_out_slow_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/d.xml-->
      <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="1550"
          android:duration="200"
          android:interpolator="@android:interpolator/fast_out_slow_in" />
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      <!--res/animator/esig.xml-->
       <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="1800"
          android:duration="600"
          android:interpolator="@android:interpolator/fast_out_linear_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/n.xml-->
       <?xml version="1.0" encoding="utf-8"?>
       <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="2450"
          android:duration="200"
          android:interpolator="@android:interpolator/fast_out_slow_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/i_dot.xml-->
      <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="1400"
          android:duration="50"
          android:interpolator="@android:interpolator/fast_out_slow_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/second_i_dot.xml-->
      <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="2700"
          android:duration="50"
          android:interpolator="@android:interpolator/fast_out_slow_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/a_stroke.xml-->
      <?xml version="1.0" encoding="utf-8"?>
      <objectAnimator
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="trimPathEnd"
          android:valueFrom="0"
          android:valueTo="1"
          android:startOffset="1300"
          android:duration="50"
          android:interpolator="@android:interpolator/fast_out_slow_in" />           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 建立AnimatedVectorDrawable
      <animated-vector
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:drawable="@drawable/android_design">
            <target
          android:name="andro"
          android:animation="@animator/andro" />
      
          <target
              android:name="id"
              android:animation="@animator/id" />
      
          <target
              android:name="a_stroke"
              android:animation="@animator/a_stroke" />
      
          <target
              android:name="i_dot"
              android:animation="@animator/i_dot" />
      
          <target
              android:name="d"
              android:animation="@animator/d" />
      
          <target
              android:name="esig"
              android:animation="@animator/esig" />
      
          <target
              android:name="n"
              android:animation="@animator/n" />
      
          <target
              android:name="second_i_dot"
              android:animation="@animator/second_i_dot" />
      
          <target
              android:name="andro"
              android:animation="@animator/color"/>
      </animated-vector>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
    • 使用AnimatedVectorDrawerable
      private ImageView imageView;
      private AnimatedVectorDrawable avd;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          imageView = (ImageView) findViewById(R.id.image_view);
          avd = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_android_design);
          imageView.setImageDrawable(avd);
      }
      
      public void click(View view) {
          avd.start();
      }           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
  3. clip-path 實作填充或者镂空。 

    主要使用到的是clip-path這個标簽。這個标簽對目前group和child group 有效。而且,定義clip-path後,知會對clip-path後面的path産生效果。而不會對clip-path前産生效果。例如:

    • 定義vectorDrawable
      <!--res/drawable/ic_heart.xml-->
      <vector
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:width="280dp"
          android:height="280dp"
          android:viewportWidth="56"
          android:viewportHeight="56">
          <path
              android:name="full"
              android:pathData="@string/heart_full_path"
              android:fillColor="#2c32f1" />
          <clip-path
              android:name="clip"
              android:pathData="@string/heart_clip_hidden" />
          <path
              android:name="empty"
              android:pathData="@string/heart_empty_path"
              android:fillColor="#2cf2af" />
      </vector>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      這個例子中的clip-path值對empty這個path有效,而無法影響full這個path。
    • 定義需要用到的動畫
      <!--res/animator/empty_heart.xml-->
          <objectAnimator 
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:propertyName="pathData"
              android:fromValue="@string/heart_clip_shown"
              android:toValue="@string/heart_clip_hidden"
              android:duration="1000"
              android:interpolator="@android:interpolator/fast_out_slow_in"
              android:valueType="pathType"/>
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--res/animator/full_heart.xml-->
      <objectAnimator 
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:propertyName="pathData"
          android:fromValue="@string/heart_clip_hidden"
          android:toValue="@string/heart_clip_shown"
          android:duration="1000"
          android:interpolator="@android:interpolator/fast_out_slow_in"
          android:valueType="pathType"/>
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      <!--各個path要用到的pathData-->
          <string name="heart_empty_path">M32.95,19 C31.036,19 29.199,19.8828338 28,21.2724796 C26.801,19.8828338 24.964,19 23.05,19 C19.6565,19 17,21.6321526 17,24.9945504 C17,29.1089918 20.74,32.4713896 26.405,37.5667575 L28,39 L29.595,37.5667575 C35.26,32.4713896 39,29.1089918 39,24.9945504 C39,21.6321526 36.3435,19 32.95,19 L32.95,19 Z M28.1155,35.9536785 L28,36.0572207 L27.8845,35.9536785 C22.654,31.2506812 19.2,28.1444142 19.2,24.9945504 C19.2,22.8201635 20.8555,21.1798365 23.05,21.1798365 C24.744,21.1798365 26.394,22.2643052 26.9715,23.7520436 L29.023,23.7520436 C29.606,22.2643052 31.256,21.1798365 32.95,21.1798365 C35.1445,21.1798365 36.8,22.8201635 36.8,24.9945504 C36.8,28.1444142 33.346,31.2506812 28.1155,35.9536785 L28.1155,35.9536785 Z</string>
          <string name="heart_full_path">M28,39 L26.405,37.5667575 C20.74,32.4713896 17,29.1089918 17,24.9945504 C17,21.6321526 19.6565,19 23.05,19 C24.964,19 26.801,19.8828338 28,21.2724796 C29.199,19.8828338 31.036,19 32.95,19 C36.3435,19 39,21.6321526 39,24.9945504 C39,29.1089918 35.26,32.4713896 29.595,37.5667575 L28,39 L28,39 Z</string>
          <string name="heart_clip_hidden">M18 37 L38 37 L38 37 L18 37 Z</string>
          <string name="heart_clip_shown">M0 0 L56 0 L56 56 L0 56 Z</string>
                 
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 定義AnimatedVectorDrawable
      <!--res/drawable/avd_heart_empty.xml-->
          <animated-vector
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:drawable="@drawable/ic_heart">
              <target
                  android:name="clip"
                  android:animation="@animator/empty_heart"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      <!--res/drawable/avd_heart_full.xml-->
          <animated-vector
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:drawable="@drawable/ic_heart">
              <target
                  android:name="clip"
                  android:animation="@animator/ful_heart"/>           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 代碼中使用AnimatedVectorDrawable 
      ...
          private ImageView mHeartImg;
          private AnimatedVectorDrawable avdHeart;
      
          @Override
          public void onCreate(Bundle savedInstance){
              mHeartImg = (ImageView)findViewById(R.id.img_heart);
              avdHeart = (AnimatedVectorDrawable)getDrawable(R.drawable.avd_heart_full);
          }
      
          @Overide
          public void onClick(View v){
              mHeartImg .setImageDrawable(avdHeart);
              avdHeart.start();
          }
          ...           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

制作vector

先制作svg,再将svg轉換成android的vector drawable. 

1. 線上制作svg, 

2. 線上svg轉換為vector