![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90zdZZDbYVGMShEZvB3MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zN3gjNyYTN2EDMzgDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
1、svg圖檔
svg和bitmap的差別 不詳細介紹了
首先強烈推薦阿裡 iconfont 簡單粗暴
找一張圖檔下載下傳 可以調整圖檔屬性 選擇svg下載下傳
然後打開android studio module 右鍵drawable
選中下載下傳的svg圖檔 這裡可以調整圖檔屬性 然後生成對應的.xml檔案
最後的使用是一樣的 android:src="@drawable/ic_xxxxx" 等等
2、svg屬性
打開導入svg生成的xml檔案 發現是這個樣子
一臉懵逼,什麼鬼。
淡定 屬性講解
<vector xmlns:android="http://schemas.android.com/apk/res/android" //命名空間
android:height="200dp" //這個是圖檔的intrinsic高度
android:width="200dp" //這個是圖檔的intrinsic寬度
android:viewportHeight="100" //這個是為這個圖檔設定的縱坐标,表示将圖檔分為100等份,主要下面的pathData需要依賴這個坐标的劃分
android:viewportWidth="100" //同上,隻不過這個是橫坐标,這兩個值可以随便定
android:alpha="0.2" //這個是整個圖像的透明度,取值範圍0到1
>
<group //這個标簽中可以放入若幹個<path/>标簽,并給它們設定一些共同的屬性
android:name="group_name" //這個name很有用,在設定objectAnimator的時候用來區分給那個部分施加動畫
android:pivotY="50" //這個設定這個group的中心點的X坐标,取值範圍為0到100,在做rotation時有用
android:pivotX="50" //這個設定這個group的中心點的Y坐标,取值範圍為0到100,在做rotation時有用
android:translateX="20" //将整個group在X軸方向平移多少像素
android:translateY="30" //将整個group在Y軸方向平移多少像素
android:rotation="90" //将整個group以中心點左邊旋轉的角度,360為一圈
android:scaleX="0.5" //橫坐标的縮放比例 , 取值1表示100%
android:scaleY="0.3"> //縱坐标的縮放比例,取值0.5表示50%,取值1.5表示150%
<path //這個标簽是重頭戲,矢量圖繪制的路徑
android:name="path_name" //為這個path标記的名字,在使用objectAnimator的時候用來區分給哪個部分施加動畫
android:pathData="m 0,0 L50,0 L100,100 L0,100 z" //這個具體文法,在網上随便搜搜就有了,就是SVG的文法,如果這個都不明白,那麼你肯定不明白什麼是矢量圖,找點資料再看看吧,這篇文章不适合你
android:fillColor="@color/red" //圖形内部的夜色
android:fillAlpha="1" //圖形的透明度取值範圍0到1
android:strokeAlpha="0.5" //線條的透明度,取值範圍0到1
android:strokeColor="#ff0000ff" //線條的顔色
android:strokeLineCap="butt|round|square" //線的末端形狀,butt嚴格到指定的坐标就截至,round圓角的先端邊緣,square方形的邊緣不過有點向外延伸
android:strokeLineJoin="round|bevel|miter" //線的連接配接處形狀,round是圓角的,bevel和miter貌似看不出來有什麼差別....
android:strokeWidth="20" //線段的寬度
android:trimPathStart="0.5" //顧名思義,從path開始的地方(0%)去除path,去除到指定的百分比位置,取值範圍0到1
android:trimPathEnd="0.5" //顧名思義,從path結束的地方(100%的地方)去除path,去除到指定的百分比位置,取值範圍0到1
android:trimPathOffset="0.5" //這個屬性是和上面兩個屬性共同使用的,單獨使用沒有用,這個屬性的意思是,在去除path的時候設定path原點的位置,按百分比設定,取值範圍0到1
/>
</group>
</vector>
3、svg動畫
動畫 特效 。。。 頭皮發麻有沒有
svg可以打造非常炫酷的動畫 這裡先來繪制簡單的線條動畫
圖檔看起來很卡頓 但是實際運作效果是非常流暢的!
繪制動畫前 先來了解點東西
Android對于 SVG 的支援是從 Android L 開始的,它的 SDK 裡面加入了 VectorDrawable , AnimatedVectorDrawable 等類幫助我們建構 SVG 圖形以及動畫,并且你可以在 xml 檔案裡面直接使用 <vector/> 标簽繪制 SVG 圖像以及 <animated-vector/> 标簽為 SVG 圖像配置設定動畫
使用path标簽建立SVG,就像用指令的方式來控制一隻畫筆,例如移動畫筆到某一坐标位置,畫一條線,畫一條曲線,結束。path标簽所支援的指令有以下幾種。
M = moveto(M X,Y):将畫筆移動到指定的坐标位置,但未發生繪制
L = lineto(L X,Y):畫直線到指定的坐标位置
H = horizontal lineto(H X):畫水準線到指定的X軸坐标
V = vertical lineto(V Y):畫垂直線到指定的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,FLAG1,FLAG2,X,Y):弧線
Z = closepath():關閉路徑
OK 簡單了解了點屬性 那看代碼 根據代碼來推敲 效果會好很多
4根線條代碼 在drawable中建立 text.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportHeight="100"
android:viewportWidth="100">
<path
android:name="heart1"
android:pathData="
M13,20 C 9,40, 5,60, 2,80 L14,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />
<path
android:name="heart2"
android:pathData="
M30,38 C20,30,10,40,11.5,50 C11.5,58.5,20,65,30,70 C40,65,48.5,58.5,48.5,50 C50,40,40,30,30,38Z"
android:strokeColor="#E91E63"
android:strokeWidth="1" />
<path
android:name="heart3"
android:pathData="
M30,50 L30,55L30,50L35,50L30,50L60,80"
android:strokeColor="#E91E63"
android:strokeWidth="1" />
<path
android:name="heart4"
android:pathData="
M75,55 L75,65 C75,70,80,75,85,75C90,75,95,70,95,65L95,55"
android:strokeColor="#E91E63"
android:strokeWidth="1" />
</vector>
定義的寬高是256dp 然後viewportHeight viewportWidth都是100 即寬高的每個機關是2.56dp
可以用白紙畫出來 一個寬高256dp的正方形 100等分
每根線條的pathData 對應上面的屬性來了解都很簡單 現在講講愛心怎麼繪制
參考
https://www.cnblogs.com/wjtaigwh/p/6652510.html
貝塞爾曲線函數難點是在坐标定位 網上應該有很多貝塞爾曲線定點工具
先用4根貝塞爾曲線繪制個圓
再根據愛心的變化 調整幾個坐标點即可
參考 https://www.cnblogs.com/wjtaigwh/p/6652510.html
線條畫完 再加入動畫
在drawable中建立 text_vector_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/text">
<target
android:name="heart1"
android:animation="@animator/heart_animator" />
<target
android:name="heart2"
android:animation="@animator/heart_animator" />
<target
android:name="heart3"
android:animation="@animator/heart_animator" />
<target
android:name="heart4"
android:animation="@animator/heart_animator" />
</animated-vector>
在drawable中建立 heart_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="6000"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
<!-- trimPathEnd 開始到結束 trimPathStart結束到開始-->
最後在activity中調用 用的是kotlin
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
(svg_animator_text!!.drawable as Animatable).start()
完成
但是有些互動需要監聽動畫 該怎麼辦呢
上面svg動畫強轉Animatable類 進去看看
public interface Animatable {
void start();
void stop();
boolean isRunning();
}
是個接口 并且沒有監聽的方法 再看看其他強轉的類 發現有個Animatable2 并且有個AnimationCallback回調 裡面有動畫監聽
試試 發現報錯 程式都運作不起來了 怎麼辦
初探svg 還沒去看源碼怎麼辦呢
然後又發現個Animatable2Compat類 運作成功
svg_animator_text!!.setImageDrawable(AnimatedVectorDrawableCompat.create([email protected], R.drawable.text_vector_animator))
val animatable2 = svg_animator_text?.drawable as Animatable2Compat
animatable2.registerAnimationCallback(object : Animatable2Compat.AnimationCallback(){
override fun onAnimationEnd(drawable: Drawable?) {
super.onAnimationEnd(drawable)
println("onAnimationEnd")
}
override fun onAnimationStart(drawable: Drawable?) {
super.onAnimationStart(drawable)
println("onAnimationStart")
}
})
最最最後 一定要記得svg相容性 這裡就不多說了 網上很多