首先我们看一下矢量图的文件
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#EDD817"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
显示的是这么个图形
8b8c08f7efd0ff4aa10cbc9aefe3d464.png
我们来看看每个标签的意思
vector 定义的矢量图,在res/drawable/
android:name 矢量图的名称
android:width drawable的固定高度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:height drawable的固定宽度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:tint drawable 的 tint 颜色。默认是没有 tint 颜色的
android:tintMode tint 颜色的 Porter-Duff blending 模式,默认值为 src_in
android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。
android:alpha 该图片的透明度属性
其他的都很好理解,width和viewportWidth是什么意思呢,我们来看一下
viewportWidth和viewportHeight
通过studio生成svg文件
24dp.png
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#EDD817"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
我们修改一下大小
120dp.png
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="120dp"
android:height="120dp"
android:tint="#EDD817"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
我们对比一下两个文件
24dp和120dp对比.png
可以看到,两个文件基本一样,唯一的不同是width和height,viewportWidth和viewportHeight是一样的,为了方便比较,我们修改一下width、height、viewportWidth、viewportHeight这几个文件来对比一下
svg_ic_add_box_black_120dp_viewportsmall.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="240dp"
android:height="120dp"
android:tint="#EDD817"
android:viewportWidth="12.0"
android:viewportHeight="16.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
svg_ic_add_box_black_120dpc_viewportbig.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="240dp"
android:height="100dp"
android:tint="#EDD817"
android:viewportWidth="12.0"
android:viewportHeight="50.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
显示在界面上看看效果,为了方便看效果,每个view都加上黑色背景
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_24dp"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_24dp"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_120dp"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="150dp"
android:layout_height="100dp"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_120dp"
android:tint="#ff00ff"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_120dp_viewportsmall"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="100dp"
android:layout_height="200dp"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_120dp_viewportsmall"
android:tint="#00ff00"
android:layout_marginLeft="30dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:src="@drawable/svg_ic_add_box_black_120dpc_viewportbig"
android:layout_marginLeft="30dp"/>
我们看下实际的效果
svg_viewport对比.png
分析一下上图:
图1:原始大小,24dp的宽高
图2:ImageView中修改了大小为150dp,矢量图缩放为宽高150dp
图3:矢量图的width和height为120dp,显示大小120dp
图4:矢量图和图3一样,ImageView限制大小,矢量图缩放匹配最小宽高100dp
图5:这里,我们修改了矢量图width="240dp", height="120dp", viewportWidth="12.0", viewportHeight="16.0",我们看到,图片已经显示不全了,原本viewport是24,我们看宽度,改为12,从图像来看,正好是一半,viewport高度16也符合比例,是否可以认为viewport就是控制路径最终显示比例的。宽高显示符合240dp和120dp
图6:矢量图和图5是一样的,修改了ImageView的大小,layout_width="100dp" layout_height="200dp",可以看到矢量缩放为宽度100dp,图形还是没有变的
图7:我们修改了矢量图width="240dp", height="100dp", viewportWidth="12.0", viewportHeight="50.0",和图5对比,同样的就是width和height,再来看看viewport,我们设定viewportWidth="12.0",大小是24的一半,然后viewportHeight="50.0",大小是24的一倍多。看到,图形上,宽显示一半,高超出部分显示透明
得到结论:
viewportWidth和viewportHeight的大小是矢量图路径绘制的基准,比如上面的矢量图,viewport大小是24,那么这个画布就是24*24,如果路径中有点M48,48,那就超出画布边界了,当L0,0时,实际这根线只有一半长。
width和height是矢量图作为drawable显示在View中显示宽高的比例
按钮效果
如果要做按钮效果,就是按下和抬起颜色不一样,如何实现呢,我们这里在res/color下创建一个selector,配置不一样的颜色
svg_ic_select.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#f58036" android:state_pressed="true" />
<item android:color="#34ff00" android:state_pressed="false" />
</selector>
然后在使用矢量图时将这个selector指定为tint就行了
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:clickable="true"
android:src="@drawable/svg_ic_add_box_black_24dp"
android:tint="@color/svg_ic_select" />
path 定义了要被绘制的路径。
android:name 给 path 分配一个唯一的名字,这样在其他地方可以通过名字来引用这个路径,比如说动画
android:pathData 路径信息。
android:fillColor 填充路径的颜色
android:fillAlpha 填充路径的透明度
android:strokeColor 边框颜色
android:strokeWidth 边框粗细尺寸
android:strokeAlpha 边框透明度
android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到 1
android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到 1
android:trimPathOffset 设置路径截取的范围,取值范围从 0 到 1
android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.
android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.
android:strokeMiterLimit 设置斜角的上限
上面的属性大部分和Paint里的属性差不多
pathData
M = moveto 相当于 android Path 里的moveTo(),用于移动起始点
L = lineto 相当于 android Path 里的lineTo(),用于画线
H = horizontal lineto 用于画水平线
V = vertical lineto 用于画竖直线
C = curveto 相当于cubicTo(),三次贝塞尔曲线
S = smooth curveto 同样三次贝塞尔曲线,更平滑
Q = quadratic Belzier curve quadTo(),二次贝塞尔曲线
T = smooth quadratic Belzier curveto 同样二次贝塞尔曲线,更平滑
A = elliptical Arc 相当于arcTo(),用于画弧
Z = closepath 相当于closeTo(),关闭path
大写表示绝对定位,小写表示相对定位
clip-path 绘制的剪切路径
android:name clip path 的名字
android:pathData 和path的取值一样。
注意,clip-path 只对当前的 group 和子 group 有效
我们看下效果
把我们的矢量图先截取一部分
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#EDD817"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14" />
/>
</vector>
e1101be07b222346868ae905c48f8aa5.png
我们看到,先移动到点(19,3),然后连线到(5,3),然后画三阶贝赛尔曲线,然后画竖线14个像素,最终成像就是上图。接着我们把这个path还原,加上clip-path
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#EDD817"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<clip-path
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14" />
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
</vector>
698c466dc470b542bf4db52f49674130.png
看到,path还是那个path,但是被截取了一半
animated-vector 矢量资源动画
定义在res/drawable/中
我们先定义一组svg路径
svg_ic_add_box_animation.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="720dp"
android:height="240dp"
android:viewportWidth="72.0"
android:viewportHeight="24.0">
<path
android:name="box"
android:fillColor="#EDD817"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
<group android:name="boxgroup">
<path
android:name="box1"
android:fillColor="#FFD81750"
android:pathData="M27,3L45,3L45,21L27,21z" />
</group>
<group android:name="roundgroup">
<path
android:name="round"
android:fillColor="#FF38D850"
android:pathData="M60,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" />
</group>
</vector>
代码中定义了三个路径
d1070dfe5e2aff4099c681d6e4f8c379.png
group 定义了一组路径,主要是用来设置路径做动画的关键属性的
android:name group 的名字,这样在其他地方可以通过名字来引用这个路径,比如说动画
android:rotation 旋转角度
android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。
android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。
android:scaleX 定义 X 轴的缩放倍数
android:scaleY 定义 Y 轴的缩放倍数
android:translateX 定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的。
android:translateY 定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的。
注意一下,相对于 vector 的 viewport 值来指定这句话的意思,从上面分析中知道,矢量图的路径点是固定的,viewport就是路径点依赖的画布。当矢量图绘制到界面上时,是会有缩放的。所以要以viewport为基准来translate
看到group 的属性,是不是和objectAnimator 很像,我们先定义几个动画objectAnimator
objectAnimator 一个或多个对象动画器
如果要定义动画的集合,则应该在res/anim/中定义,如下
svg_animation_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueType="floatType"
android:propertyName="scaleX"
android:valueFrom="0"
android:valueTo="1"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:duration="1500">
</objectAnimator>
<objectAnimator
android:valueType="floatType"
android:propertyName="scaleY"
android:valueFrom="0"
android:valueTo="1"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:duration="1500">
</objectAnimator>
</set>
如果是单独的动画,可以在res/animator/中定义,如下
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="trimPathStart"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"/>
有了动画,就需要把动画和矢量图结合起来,这个时候就需要用到我们的animated-vector
svg_box_animation.xml
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/svg_ic_add_box_animation">
<target
android:name="boxgroup"
android:animation="@anim/svg_animation_rotation"/>
<target
android:name="roundgroup"
android:animation="@anim/svg_animation_scale"/>
<target
android:name="box"
android:animation="@anim/svg_animation_trim"/>
</animated-vector>
这里要注意一下,动画里面的android:propertyName,要与target里对应的path个group对应。如果说这个target对应的name对象是一个path,animation对应的propertyName是一个scaleX。就会抛出异常:
java.lang.IllegalArgumentException: Property: translateY is not supported for FullPath
ok,动画文件有了,加入到布局中
<ImageView
android:layout_width="wrap_content"
android:layout_height="720dp"
android:background="@android:color/black"
android:src="@drawable/svg_box_animation"
android:layout_marginLeft="30dp"
android:onClick="startBoxAnim"/>
点击启动动画
public void startBoxAnim(View view) {
Drawable drawable = ((ImageView) view).getDrawable();
((AnimatedVectorDrawable)drawable).start();
}
看一下效果
svg动画.gif
我们看到,动画是有了,不太美观。我们想让红色方框围绕自己圆心转,绿色的球也围绕自己圆心缩放,这时候就需要修改group里的参数了。前面我们知道
android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。
android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。
先来找红方的圆心,我们的viewport 是72*24,红方的pathData="M27,3L45,3L45,21L27,21z",那么,圆心就是x = 27+(45-27)/2 = 36, y = 3+(21-3)/2 = 12,所以圆心就是(36, 12)
再来看绿圆的圆心,看下pathData="M60,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" ,显然,圆心就是(60,12)
修改代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="720dp"
android:height="240dp"
android:viewportWidth="72.0"
android:viewportHeight="24.0">
<path
android:name="box"
android:fillColor="#EDD817"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
<group android:name="boxgroup"
android:pivotX="36"
android:pivotY="12">
<path
android:name="box1"
android:fillColor="#FFD81750"
android:pathData="M27,3L45,3L45,21L27,21z" />
</group>
<group android:name="roundgroup"
android:pivotX="60"
android:pivotY="12">
<path
android:name="round"
android:fillColor="#FF38D850"
android:pathData="M60,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" />
</group>
</vector>
看下效果
svg动画修改圆心.gif
代码中设置动画
AnimatedVectorDrawableCompat focus = AnimatedVectorDrawableCompat.create(this, R.drawable.svg_searchbar_focus);
view.setImageDrawable(focus);
focus.start();
代码中解析svg文件
我们拿到一个svg文件
china.svg
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="-1dp"
android:height="-1dp"
android:viewportWidth="-1"
android:viewportHeight="-1">
<path
android:fillColor="#CCCCCC"
android:strokeColor="#ffffff"
android:strokeWidth="0.5"
android:pathData="M541.02,336.29L541.71,336.09L542.54,337.38L543.77,338.27L543.53,338.58L545.92,338.99L546.76,340.12L547.78,339.82L548.44,340.06L548.55,341.76L549.62,342.38L549.24,343.35L550.53,344.12L550.58,344.54L551.35,344.98L552.82,345L553.38,344.66L554.17,345.63L555.37,345.08L556.2,346.28L556.8,345.6L557.37,346.12L557.82,347.73L558.51,347.76L558.17,350.15L560.8,350.12L561.12,349.61L562.97,349.6L563.89,349.94L563.48,350.21L563.6,351.15L562.98,351.84L562.99,353.94L562.28,353.68L562.06,353.97L561.87,355.49L561.13,355.88L561.38,356.41L560.77,357.72L561.33,357.73L561.41,358.42L562.06,359L563.49,358.5L563.75,357.85L564.17,358.09L564.64,361.19L565.52,361.68L564.51,362.21L564.67,363.38L565.17,363.21L565.35,364.41L566.19,364.53L566.23,365.29L567.26,365L568.99,365.25L569.63,364.91L570.56,365.3L571.08,364.96L570.95,363.35L571.8,363.24L571.79,362.34L572.18,362.28L572.34,361.72L573.37,362.02L574.42,361.71L574.42,362.52L574.75,362.45L575.54,363.71L576.52,363.63L576.85,365.23L576.63,366L577.12,366.98L576.92,367.48L576.48,367.11L576.07,368.69L575.27,369.28L574.63,368.34L573.95,368.48L573.38,367.72L572.81,367.73L572.98,367.22L572.16,367.55L571.92,367L571.51,367.33L570.62,366.94L568.79,367.27L568.69,367.68L569.32,368.35L569.11,368.9L570.26,368.96L570.14,370.25L570.47,370.97L569.84,371.57L569.93,372.77L567.97,373.13L567.87,374.18L566.53,374.8L566.23,376.97L567.47,378.22L567.97,378.31L567.71,378.99L568.26,379.8L569.51,379.48L570.12,379.99L570.31,380.33L569.75,380.78L569.89,381.28L570.75,381.42L571.35,380.69L571.68,381.56L572.49,381.6L572.8,383.08L572.58,384.48L571.83,385.3L571.01,385.39L570.45,386.31L571.17,386.68L571.53,387.37L575.34,387.32L576.48,386.31L576.73,386.77L577.75,387.06L578.55,386.9L578.72,386.35L579.08,386.85L578.81,387.69L579.32,387.8L579.14,388.12L582.26,388.74L582.26,388.74L582.19,390.54L581.33,392.01L581.47,393.15L580.92,394L580.4,393.97L580.39,394.99L579.82,395.87L579.45,395.93L579.08,395.35L578.2,396.29L577.28,396.38L577.6,396.9L577.29,397.52L577.68,397.88L578.35,397.61L578.64,399.27L579.28,399.98L578.8,400.22L578.35,399.91L577.41,400.34L577.11,401.08L575.34,400.59L574.8,400.87L573.67,400.08L572.75,400.72L572.88,401.97L573.27,402.26L572.33,403.02L572.9,403.12L572.57,403.81L572.98,404.99L572.9,406.09L572.21,406.26L572.04,407.05L571.14,407.62L570.94,409.22L569.81,410.43L568.54,410.96L567.72,412.46L566.89,412.46L566.65,412.91L565.57,412.67L565.46,413.7L564.67,413.56L564.03,414.13L564.03,414.13L563.23,413.7L563.3,412.5L561.74,411.47L560.73,411.87L559.19,411.51L557.87,411.88L557.23,410.94L556.38,411.36L555.76,411.18L555.42,410.78L555.63,410.36L554.66,409.87L554.68,408.98L554.1,408.32L554.24,407.54L553.46,408.06L553.18,407.52L552.62,407.92L552.19,407.79L552.13,406.67L551.61,406.4L550.63,406.74L550.57,407.32L549.85,407.78L550.64,408.52L550.35,409.52L548.88,409.93L546.92,411.56L546.35,411.62L545.91,411.15L545.41,411.64L544.54,410.6L544.91,410.04L544.56,409.77L545.8,408.28L546.56,408.07L547.67,406.07L547.27,405.63L546.78,405.76L546.74,405.21L546.38,405.28L546.2,404.83L544.73,404.27L543.76,404.56L543.09,406.83L542.24,406.82L539.6,408.5L538.88,407.79L538,407.92L538,407.92L537.97,406.96L537.23,405.88L537.45,404.82L537.12,402.37L536.23,401.64L536.06,401.04L535.09,400.83L535.24,400.47L534.83,399.78L535.59,399.16L534.97,398.75L535.21,397.8L534.66,396.77L533.92,396.67L533.84,395.95L533.26,395.38L533.52,394.35L534.62,394.05L534.3,393.18L534.62,392.72L537.23,391.28L536.87,390.53L535.54,390.11L534.7,388.6L533.39,389.1L532.51,387.8L531.94,387.66L530.97,388.6L530.32,387.03L529.52,386.78L529.48,386.12L529.14,385.61L528.55,385.68L528.33,384.83L528.33,384.83L528.41,383.41L529.8,381.78L529.94,380.84L532.2,379.27L532.81,379.54L533.34,379.19L533.94,379.57L535.17,379.04L534.92,377.86L535.29,377.27L535.49,373.58L535.12,372.75L534.78,368.75L534.3,368.46L535.34,367.54L534.96,367.42L533.5,369.09L533.31,368.51L533.16,368.93L532.38,368.65L532,369.91L531.13,369.65L530.61,370.02L530.78,369.79L528.8,367.47L527.48,367.8L527.47,367.3L526.14,367.25L526.14,363.27L525.37,362.59L524.05,362.5L523.79,362.02L522.89,362.08L522.15,361.35L522.76,360.8L522.33,359.84L522.44,359.18L522.85,358.72L524.05,359.8L525.49,359.83L526.01,359.28L527.33,359.09L528.25,356.19L527.62,355.4L528.01,353.55L528.37,353.28L528.68,353.53L528.87,352.71L530.69,352.71L531.71,352.3L530.81,349.43L531.44,349.31L531.64,347.98L530.57,347.83L531.23,345.53L531.87,345.02L533.86,344.93L534.43,345.96L534.87,345.52L535.88,345.99L536.29,346.55L536.09,347.44L537.04,348.1L536.87,348.57L537.23,349.32L538.33,350.45L541.8,348.99L541.87,348.25L542.88,347.98L543.42,347.42L544.39,347.69L544.48,346.42L542.96,344.27L543.48,343.38L543.14,342.56L543.61,341.8L542.65,341.52L542.06,341.94L541.92,341.58L540.93,341.91L540.88,341.21L538.99,340.21L538.31,338.99L538.82,338.19L538.71,337.22L538.71,337.22L539.3,337.63L539.84,336.78L540.31,336.88z" />
<path
android:fillColor="#CCCCCC"
android:strokeColor="#ffffff"
android:strokeWidth="0.5"
android:pathData="M546.46,257.82L546.2,258.07L545.19,257.69L545.32,258.18L543.93,257.5L543.54,257.65L542.41,258.89L541.38,259.38L542.02,260.56L540.61,260.4L539.44,259.53L539.28,258.7L538.66,258.32L537.92,258.56L536.13,258.13L535.82,258.52L535.34,258.01L535.11,258.57L534.23,258.84L533.87,259.42L533.2,259.42L532.34,257.98L530.81,258.02L529.74,257.1L529.84,255.69L529,255.13L530.84,254.47L530.2,254L530.15,252.87L528.99,252.2L529.29,251L531.38,249.47L533.13,249.19L533.53,248.49L534.28,249.13L534.78,247.81L535.79,247.12L535.17,245.59L534.67,245.52L533.4,244.1L533.46,243.33L532.94,243.15L533.23,242.5L535.15,241.24L536.1,241.87L537.59,241.28L539.29,238.42L540,238.94L541.47,238.45L542.04,238.74L542.1,238.37L540.49,236.54L540.53,236.05L540.92,235.88L541.32,236.49L542.23,236.64L541.97,235.28L543.78,235.25L543.95,234.15L544.4,233.9L545.04,234.33L544.79,235.26L545.4,236.52L546.36,237.49L547.05,237.66L548.92,239.98L550.77,239.84L552.86,240.63L554.07,240.2L555.26,240.44L555.25,240.92L554.58,240.66L554.36,240.98L554.53,241.89L552.78,241.9L551.97,242.41L552.11,242.94L551.46,243.23L551.9,244.24L551.74,245.25L553.34,247.62L553.79,247.69L553.79,247.69L553.79,248.62L551.45,250.07L551.45,250.07L549.71,250.41L548.96,250.95L548.26,250.65L546.19,250.97L545.91,251.98L546.21,253.02L547.91,253.88L548.31,254.99L547.73,255.44L547.66,256.41L547.66,256.41L547.72,256.71L547.07,256.96z" />
//后面省略
</vector>
这是一个中国地图的svg,每个path代表一个省,如何解析这个文件呢
final InputStream inputStream = context.getResources().openRawResource(R.raw.china);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //取得DocumentBuilderFactory实例
DocumentBuilder builder = null; //从factory获取DocumentBuilder实例
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(inputStream); //解析输入流 得到Document实例
Element rootElement = doc.getDocumentElement();
NodeList items = rootElement.getElementsByTagName("path");
List<ProviceItem> list = new ArrayList<>();
for (int i = 0; i < items.getLength(); i++) {
Element element = (Element) items.item(i);
String pathData = element.getAttribute("android:pathData");
Path path = PathParser.createPathFromPathData(pathData);
RectF rect = new RectF();
path.computeBounds(rect, true);
list.add(proviceItem);
}
itemList = list;
} catch (Exception e) {
e.printStackTrace();
}
PathParser.createPathFromPathData可以将SVG中pathData直接转成我们canvas中需要用到的path
path.computeBounds(rect, true);这段代码可以求出不规则path的边界范围
最后将path绘制到界面上
中国地图.png
网友评论