SVG 图像技术(Scalable Vector Graphics ,可缩放的矢量图形)是目前较为新颖的图像文件格式,基于 XML 框架,具有以下优势。
- 无损的扩展分辨率
- 文件体积小
- 支持动画
在 Android 系统中, SVG 图像技术的实现方式是 Vector 图像,我们在写应用时用到的很多 .png
格式的图标通常都要准备两个高低分辨率的图片,这是使用 SVG 图像则可有效的缩小应用的体积。下面看看如何使用和生成 Vector 图像。
SVG 图片
- 获取
.svg
格式的图像文件,这里推荐一个图标网站 阿里巴巴矢量图标库 - 创建图像,在 Android Studio 中,依次选择:【 file 】/【 New 】/【 Vector Asset 】,勾选 Local file 并在电脑本地选择下载好的文件。
- 设置进布局代码中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_milky" />
</LinearLayout>
可以看到图像文件被生成了 ic_milky.xml
代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FFFFFF"
android:pathData="M758.6,344.6C742.4,226.7 641.4,135.9 519,135.9s-223.4,90.8 -239.6,208.7h479.2z" />
<path
android:fillColor="#E5E5E5"
android:pathData="M519.1,135.9c-12.2,0 -24.1,0.9 -35.8,2.6 104.7,16.6 187,100.3 201.4,205.7H279.6c0,0.1 0,0.2 -0.1,0.4h479.1c-16.1,-117.9 -117.2,-208.7 -239.5,-208.7zM226,344.9h582.2v89.6H226z" />
<path
android:fillColor="#FF954D"
android:pathData="M295,580.1s41.4,-11.8 92.2,-15.2c8.4,-0.6 17.1,-0.9 25.9,-0.9 61.8,0 158.5,35.8 212.3,35.8 10.1,0 20.3,-0.6 30.3,-1.6 43.3,-4.4 81.9,-16.1 81.9,-16.1h-0.1l-47,327.8c-2.2,15.5 -15.5,27 -31.2,27H373.4c-15.7,0 -28.9,-11.5 -31.1,-27l-47.6,-329.4" />
<path
android:fillColor="#FF6545"
android:pathData="M655.6,598.2c-2.7,0.3 -5.5,0.5 -8.3,0.7L613.4,835c-2.2,15.5 -15.5,27 -31.2,27H335.4l6.9,47.9c2.2,15.5 15.5,27 31.1,27h285.8c15.7,0 28.9,-11.5 31.2,-27l47,-327.7c-1.5,0.4 -39.4,11.7 -81.8,16zM737.4,582.1c0.1,0 0.1,0 0,0z" />
<path
android:fillColor="#333333"
android:pathData="M656.2,960.2H370.4c-25.6,0 -47.6,-19.1 -51.2,-44.4l-31.8,-221.3c-1.6,-11.1 6.1,-21.3 17.2,-22.9 11.1,-1.6 21.3,6.1 22.9,17.2L359.3,910c0.8,5.5 5.6,9.6 11.1,9.6h285.8c5.5,0 10.3,-4.1 11.1,-9.6L710,612.3c-15.2,3.4 -34.8,7 -55.5,9.1 -11.4,1.2 -22.3,1.7 -32.3,1.7 -28.3,0 -64.9,-8.5 -103.6,-17.5 -38.8,-9 -79,-18.3 -108.6,-18.3 -7.9,0 -16.1,0.3 -24.5,0.8 -48.1,3.2 -87.5,14.3 -87.9,14.4 -1.2,0.3 -2.5,0.6 -3.7,0.7 -10.7,1 -20.4,-6.6 -21.9,-17.3l-18,-125.2h-31.7c-11.2,0 -20.3,-9.1 -20.3,-20.3V351c0,-11.2 9.1,-20.3 20.3,-20.3h34.5c11.5,-55.4 40.8,-105.8 83.7,-143.5 47.8,-42 109.2,-65.2 173,-65.2s125.2,23.1 173,65.2c42.9,37.7 72.2,88.1 83.7,143.5h34.5c11.2,0 20.3,9.1 20.3,20.3v89.6c0,11.2 -9.1,20.3 -20.3,20.3H773l-2.3,15.9c-1.6,11.1 -11.8,18.8 -22.9,17.2 -11.1,-1.6 -18.8,-11.9 -17.2,-22.9l4.8,-33.3c1.4,-10 10,-17.4 20,-17.4h29v-49.1h-31.3c-10.1,0 -18.7,-7.5 -20.1,-17.5 -14.9,-109 -109.3,-191.2 -219.5,-191.2S308.9,244.8 294,353.8c-1.4,10 -9.9,17.5 -20.1,17.5h-31.3v49.1h29c10.1,0 18.6,7.4 20,17.4l17.3,120.5c17.7,-3.8 44.2,-8.5 73.9,-10.5 9.3,-0.6 18.4,-0.9 27.2,-0.9 34.3,0 76.7,9.8 117.8,19.4 36.5,8.5 70.9,16.5 94.5,16.5 8.7,0 18.2,-0.5 28.3,-1.5 37.2,-3.8 71.1,-13.3 77.2,-15.1 3.1,-1.1 6.4,-1.4 9.7,-0.9 9.4,1.4 16.5,9.1 17.2,18.6 0.1,1.9 0,3.8 -0.4,5.6L707.4,916c-3.6,25.1 -25.6,44.2 -51.2,44.2z" />
<path
android:fillColor="#333333"
android:pathData="M583.7,371.3c-4.2,0 -8.4,-1.3 -12.1,-4 -9,-6.7 -10.8,-19.4 -4.1,-28.3L746.4,98.7c3,-4 7.3,-6.7 12.1,-7.7l129.2,-26.7c11,-2.3 21.7,4.8 23.9,15.7 2.3,11 -4.8,21.7 -15.7,23.9L774.3,129 599.9,363.1c-3.9,5.4 -10,8.2 -16.2,8.2z" />
<path
android:fillColor="#FFA73E"
android:pathData="M652.9,371.3H372c-11.2,0 -20.3,-9.1 -20.3,-20.3 0,-11.2 9.1,-20.3 20.3,-20.3h280.9c11.2,0 20.3,9.1 20.3,20.3 -0.1,11.2 -9.1,20.3 -20.3,20.3zM654.2,460.8H370.7c-11.2,0 -20.3,-9.1 -20.3,-20.3 0,-11.2 9.1,-20.3 20.3,-20.3h283.5c11.2,0 20.3,9.1 20.3,20.3 0,11.3 -9.1,20.3 -20.3,20.3z" />
</vector>
Vwctor 动画
使用动态图像需要最低支持库( Android Support Library )的版本达到 23.2 及以上。
Android 系统 5.0 及以上( minSdkVersion 21 )
播放 Vector 动态图像需要用到三个文件
- 静态的图像文件
v_heard.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="70"
android:viewportHeight="70">
<path
android:name="heart1"
android:pathData="
M58.3,10.6C51.4,3.6,40,3.7,32,10.5c-1.3-1.1-2.6-2-4.1-2.8l-5.5-3.8c-0.3-0.2-0.6-0.2-1-0.1c-0.3,0.1-0.5,0.4-0.6,0.8l-0.2,1C15,4.9,9.6,6.7,5.7,10.6C-1.8,18.1-2,30,5.4,37.8L31.3,64c0.2,0.2,0.4,0.3,0.7,0.3s0.5-0.1,0.7-0.3l25.9-26.2C65.9,30.2,65.7,18,58.3,10.6z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart2"
android:pathData="
M57.2,36.4L32,61.8L6.8,36.4c-1-1-1.8-2.1-2.5-3.3l7.5,3.4c0.4,0.2,0.8,0.3,1.2,0.3c0.4,0,0.8-0.1,1.1-0.2l0.7,6.4c0,0.5,0.4,0.8,0.8,0.9l9.4,1.4c0,0,0.1,0,0.1,0c0.3,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.6,0.2-0.9l-4-17.6l13.3,11.9c0.2,0.2,0.4,0.3,0.7,0.3c0.1,0,0.2,0,0.2,0c0.3-0.1,0.6-0.3,0.7-0.6l3.2-8.9c0.2-0.4,0-0.9-0.4-1.2l-5.3-3.6c0.6-0.5,1.1-1.3,1.1-2.1l0.7-9.1c0-0.3-0.1-0.7-0.4-0.9c-0.3-0.2-0.7-0.2-1-0.1l-3.6,1.5l1.1-0.9c0,0,0,0,0,0c0,0,0,0,0,0c7.2-6.7,17.8-7,24.2-0.6C63.5,18.6,63.7,29.6,57.2,36.4z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart3"
android:pathData="
M14.3,20.7l1.6,1.9L5.3,26.4l-0.9-9.1L14.3,20.7z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart4"
android:pathData="
M19.5,18.3l1.5,3.8 l-2,1.2l-2.6-3.1L19.5,18.3z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart5"
android:pathData="
M17.2,24.3C17.3,24.3,17.3,24.3,17.2,24.3l0.4,0.5L14,34c0,0,0,0,0,0l0,0c-0.1,0.3-0.3,0.5-0.5,0.6c-0.3,0.1-0.6,0.1-0.8,0l-6.8-3.1l7.6-5.9L17.2,24.3z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart6"
android:pathData="
M22.4,23.5 l9.6,1.2l6.2,4.3l-2.5,6.8L22.2,23.7L22.4,23.5z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart7"
android:pathData="
M33.8,21.9c0,0.3-0.2,0.6-0.4,0.7c-0.2,0.2-0.5,0.2-0.9,0.2l-9.6-1.2l-0.3-0.7 l3.3-2.8l8.4-3.6L33.8,21.9z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart8"
android:pathData="
M30.4,11.9l-8.4,7L21,16.5c0,0,0-0.1-0.1-0.1l1.9-9.5c0,0,0.2,0,0.2,0s0,0,0,0l-0.2-0.4L30.4,11.9z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart9"
android:pathData="
M7.1,12c3.5-3.5,8.2-5.1,13.3-4.5l-1.5,8.8l-4.1,2.4L4.5,15.3C5.3,14.1,6.1,13,7.1,12z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
<path
android:name="heart10"
android:pathData="
M2.6,19.6l0.8,8.3c0,0.3,0.2,0.6,0.5,0.7c0.2,0.1,0.3,0.2,0.5,0.2c0.1,0,0.2,0,0.3-0.1l2.7-1L3.3,31c0,0,0,0,0,0C1.8,27.4,1.6,23.3,2.6,19.6z"
android:strokeWidth="1"
android:strokeColor="#E91E63" />
</vector>
- 动态图像资源文件
v_heard_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/v_heard">
<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" />
<target
android:name="heart5"
android:animation="@animator/heart_animator" />
<target
android:name="heart6"
android:animation="@animator/heart_animator" />
<target
android:name="heart7"
android:animation="@animator/heart_animator" />
<target
android:name="heart8"
android:animation="@animator/heart_animator" />
<target
android:name="heart9"
android:animation="@animator/heart_animator" />
<target
android:name="heart10"
android:animation="@animator/heart_animator" />
</animated-vector>
- 属性动画文件
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"/>
- 布局设置静态的图片
<?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"
tools:context=".AnimationActivity">
<Button
android:id="@+id/main_b_draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绘制"
tools:ignore="HardcodedText"/>
<ImageView
android:id="@+id/main_iv_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:src="@drawable/v_heard"/>
</RelativeLayout>
- 代码设置动画,将动态图片资源文件
v_heard_animation.xml
转化为动画向量图像类AnimatedVectorDrawable
,将图像添加至图像控件mIvImageView
,调用动态图像的start()
方法。
public class AnimationActivity extends AppCompatActivity {
private ImageView mIvImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
mIvImageView = findViewById(R.id.main_iv_image_view);
animateImage();
// 重绘动画
findViewById(R.id.main_b_draw).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
animateImage();
}
});
}
/**
* 动画播放图片
* 只支持5.0以上.
*/
private void animateImage() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 获取动画效果
AnimatedVectorDrawable mAnimatedVectorDrawable = (AnimatedVectorDrawable)
ContextCompat.getDrawable(getApplication(), R.drawable.v_heard_animation);
mIvImageView.setImageDrawable(mAnimatedVectorDrawable);
if (mAnimatedVectorDrawable != null) {
mAnimatedVectorDrawable.start();
}
}
}
}
运行效果如下。