svg使用技巧

什么是svg

SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector Graphics)。其他图像格式都是基于像素处理的,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。

位图vs矢量图

位图

比如png等,是由像素点构成的图像,对于不同的屏幕需要不同的适配,同一张图片在不同屏幕上可能会失真。

在这里插入图片描述

Android系统在使用png等位图时如下图:
在这里插入图片描述

会将不同dpi的图片先经过解码之后再绘制显示在屏幕上。

矢量图

矢量图是用xml文件来存放图片绘制的矢量信息,可以适配不同的屏幕,不会因为拉伸等导致图片失真。

在这里插入图片描述

Android中svg中的过程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GlFmCdLG-1691499986208)(https://tech-proxy.bytedance.net/tos/images/1691499961169_15b778593f5d72d21a356436b6715a1e)]

svg结构

svg保存在xml文件里面,是一棵树如下图:

在这里插入图片描述

一个简单的svg对应的xml如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:width="20dp"android:height="20dp"android:viewportWidth="20"android:viewportHeight="20"tools:ignore="MissingDefaultResource"><pathandroid:pathData="M19.3188,18.0273L13.232,11.9406C14.1766,10.7195 14.6875,9.2266 14.6875,7.6563C14.6875,5.7766 13.9539,4.0141 12.6273,2.6852C11.3008,1.3563 9.5336,0.625 7.6563,0.625C5.7789,0.625 4.0117,1.3586 2.6852,2.6852C1.3563,4.0117 0.625,5.7766 0.625,7.6563C0.625,9.5336 1.3586,11.3008 2.6852,12.6273C4.0117,13.9563 5.7766,14.6875 7.6563,14.6875C9.2266,14.6875 10.7172,14.1766 11.9383,13.2344L18.025,19.3188C18.1,19.3938 18.2219,19.3938 18.2969,19.3188L19.3188,18.2992C19.3938,18.2242 19.3938,18.1023 19.3188,18.0273ZM11.3687,11.3687C10.375,12.3602 9.0578,12.9062 7.6563,12.9062C6.2547,12.9062 4.9375,12.3602 3.9437,11.3687C2.9523,10.375 2.4063,9.0578 2.4063,7.6563C2.4063,6.2547 2.9523,4.9352 3.9437,3.9437C4.9375,2.9523 6.2547,2.4063 7.6563,2.4063C9.0578,2.4063 10.3773,2.95 11.3687,3.9437C12.3602,4.9375 12.9062,6.2547 12.9062,7.6563C12.9062,9.0578 12.3602,10.3773 11.3687,11.3687Z"android:fillColor="#1F2329"android:fillType="evenOdd"/>
</vector>

上面xml中

1、path对应路径

2、M代表移动画笔到对应的坐标 (move

3、L代表直线(line

4、C代表绘制曲线(curve

5、A代表弧线(Arc

6、Z表示结束(close)

Android 中使用svg

项目配置

在app的build.gradle文件的defaultConfig中添加vectorDrawables.useSupportLibrary = true如下:

android {defaultConfig {vectorDrawables.useSupportLibrary = true}
}

图片所在module的build.gradle中也添加上

android {defaultConfig {vectorDrawables.useSupportLibrary = true}
}

图片导入

figma上一些小的图片可以下载svg格式:

在这里插入图片描述

在Android studio按下面方式进行导入

在这里插入图片描述

导入后会自动生成xml文件

search.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:width="20dp"android:height="20dp"android:viewportWidth="20"android:viewportHeight="20"tools:ignore="MissingDefaultResource"><pathandroid:pathData="M19.3188,18.0273L13.232,11.9406C14.1766,10.7195 14.6875,9.2266 14.6875,7.6563C14.6875,5.7766 13.9539,4.0141 12.6273,2.6852C11.3008,1.3563 9.5336,0.625 7.6563,0.625C5.7789,0.625 4.0117,1.3586 2.6852,2.6852C1.3563,4.0117 0.625,5.7766 0.625,7.6563C0.625,9.5336 1.3586,11.3008 2.6852,12.6273C4.0117,13.9563 5.7766,14.6875 7.6563,14.6875C9.2266,14.6875 10.7172,14.1766 11.9383,13.2344L18.025,19.3188C18.1,19.3938 18.2219,19.3938 18.2969,19.3188L19.3188,18.2992C19.3938,18.2242 19.3938,18.1023 19.3188,18.0273ZM11.3687,11.3687C10.375,12.3602 9.0578,12.9062 7.6563,12.9062C6.2547,12.9062 4.9375,12.3602 3.9437,11.3687C2.9523,10.375 2.4063,9.0578 2.4063,7.6563C2.4063,6.2547 2.9523,4.9352 3.9437,3.9437C4.9375,2.9523 6.2547,2.4063 7.6563,2.4063C9.0578,2.4063 10.3773,2.95 11.3687,3.9437C12.3602,4.9375 12.9062,6.2547 12.9062,7.6563C12.9062,9.0578 12.3602,10.3773 11.3687,11.3687Z"android:fillColor="#1F2329"android:fillType="evenOdd"/>
</vector>

在布局中引用

<ImageViewandroid:id="@+id/Search"android:layout_width="@dimen/size_24_dp"android:layout_height="@dimen/size_24_dp"android:layout_marginEnd="@dimen/size_14_dp"android:src="@drawable/search"/>

修改svg图片颜色

有时候设计给的图片一样但是颜色不同,如果每一个颜色svg都导入会增加包大小,可以通过在引用svg的xml中通过tint设置svg图片的颜色。

<ImageViewandroid:id="@+id/Search"android:layout_width="@dimen/size_24_dp"android:layout_height="@dimen/size_24_dp"android:layout_marginEnd="@dimen/size_14_dp"android:src="@drawable/search"app:tint="@color/c_00B8E5" />

在这里插入图片描述

svg图片添加点击态

有时候需要根据不同状态显示不同颜色,svg中可以实现这种功能,首先定义一个color类型的selector。在res目录下创建一个color的文件夹,然后创建search_selector.xml如下:

<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:color="@color/c_00B8E5" android:state_pressed="true" /><item android:color="@color/black" />
</selector>

在需要点击态的xml中通过tint来控制颜色变化

<ImageViewandroid:id="@+id/Search"android:layout_width="@dimen/size_24_dp"android:layout_height="@dimen/size_24_dp"android:clickable="true"android:focusable="true"android:src="@drawable/search"app:tint="@color/search_selector" />

在这里插入图片描述

svg使用优化

在 api level 21以上使用svg默认情况下

1、会在drawable-anydpi-v24中生成seach.xml文件

在这里插入图片描述

search.xml的大小为673B

2、会在drawable-xxhdpi-v4中生成seach.png文件

在这里插入图片描述

search.png的大小为1.2kB

由于使用svg时生成了png图片所以包大小并没有减少。一定要配置

android {defaultConfig {vectorDrawables.useSupportLibrary = true}
}

可以使用下面的方式使得的apk中不生成png图片,只保留svg的xml文件。

svg动画使用

如下在布局中添加svg的xml作为srcCompat

<androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/breakHeart"android:layout_width="160dp"android:layout_height="160dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/break_heart_anim" />

其中break_heart_anim.xml是svg动画xml。

<animated-vector xmlns:tools="http://schemas.android.com/tools"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:aapt="http://schemas.android.com/aapt"tools:targetApi="lollipop"><aapt:attr name="android:drawable"><vectorandroid:name="heartbreak"android:width="56dp"android:height="56dp"android:viewportWidth="56"android:viewportHeight="56"><groupandroid:name="broken_heart_left_group"android:pivotX="28"android:pivotY="37.3"><pathandroid:name="broken_heart_left"android:pathData="M 28.031 21.054 C 28.02 21.066 28.01 21.078 28 21.09 C 26.91 19.81 25.24 19 23.5 19 C 20.42 19 18 21.42 18 24.5 C 18 28.28 21.4 31.36 26.55 36.03 L 28 37.35 L 28.002 37.348 L 27.781 36.988 L 28.489 36.073 L 27.506 34.764 L 28.782 33.027 L 26.944 31.008 L 29.149 28.725 L 27.117 27.143 L 29.149 25.018 L 26.488 22.977 L 28.031 21.054 L 28.031 21.054 Z"android:fillColor="#ff0000"/></group>...</vector></aapt:attr><target android:name="broken_heart_left_group"><aapt:attr name="android:animation"><objectAnimatorandroid:propertyName="rotation"android:duration="400"android:valueFrom="0"android:valueTo="-20"android:valueType="floatType"android:interpolator="@android:interpolator/linear_out_slow_in"/></aapt:attr></target></animated-vector>

在代码中使用下面方式开启动画

breakHeart.setOnClickListener  { if (breakHeart.drawable is AnimatedVectorDrawable) {(breakHeart.drawable as AnimatedVectorDrawable).start()}} 

动画效果如下

请添加图片描述

svg优点

1、svg比png,webp等小。

在这里插入图片描述

在这里插入图片描述

可以看到上面png和xml的大小对比,使用png大小差不多是xml的一倍。

2、svg放大不会失真

在这里插入图片描述

svg缺点

svg不支持硬件加速,所以渲染速度比png慢,下图是微信的数据对比

在这里插入图片描述
在这里插入图片描述

SVG在加载的过程中得到非常大优势,而Draw的时候因为没有硬件渲染导致性能远不如PNG。但通过在加载阶段的大幅提升,让SVG在整体耗时上赢了PNG。

svg兼容性

在这里插入图片描述

Android 4.4(API level 20)及以下版本,有两种解决方案 :

① 将矢量图生成为 PNG 图片 ;

② 使用 23.2 及以上版本的支持库 ;

在app的build.gradle文件中添加:

android {defaultConfig {generatedDensities = ['xhdpi',  'xxhdpi']}
}

Android 5.0(API level 21)及以上版本,可以直接使用vector.xml文件,不需要将vector.xml文件转换成png。但是需要在build.gradle中添加

android {defaultConfig {vectorDrawables.useSupportLibrary = true}
}

svg批量转换工具

https://github.com/MegatronKing/SVG-Android/tree/master/svg-vector-cli

使用方法

command line introductions
[-d/-dir] the target svg directory
[-f/-file] the target svg file
[-o/output] the output vector file or directory
[-w/width] the width size of target vector image
[-h/height] the height size of target vector image
command line samples
java -jar svg2vector-cli.jar -d D:\svg
or
java -jar svg2vector-cli.jar -f D:\svg\icon_facebook.svg
or
java -jar svg2vector-cli.jar -d D:\svg -o D:\vector
or
java -jar svg2vector-cli.jar -f D:\svg\icon_facebook.svg -o D:\vector\icon_facebook.xml
or
java -jar svg2vector-cli.jar -d D:\svg -o D:\vector -w 24 -h 24
or
java -jar svg2vector-cli.jar -f D:\svg\icon_facebook.svg -o D:\vector\icon_facebook.xml -w 24 -h 24

todo:

tint修改的是fillColor有些情况下点击态只需要修改strokeColor不需要修改fillColor

android:fillColor="#ffffff"
android:strokeColor="#2A97B9"/>

参考

1、https://developer.mozilla.org/en-US/docs/Web/SVG

2、https://developer.android.com/studio/write/vector-asset-studio

3、https://www.androidhive.info/2017/02/android-working-svg-vector-drawables/

4、https://developer.android.com/topic/libraries/support-library/packages?hl=zh-cn

5、https://www.growfox.co.uk/blog/5-reasons-you-should-be-using-svgs-over-pngs

6、https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207863967&idx=1&sn=3d7b07d528f38e9f812e8df7df1e3322&scene=4#wechat_redirect

4、https://medium.com/android-dev-hacks/android-vector-drawables-bfb515ba8f2e

5、https://tech.bytedance.net/articles/11584

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/58296.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瞅一眼nginx

目录 &#x1f9ac;什么是nginx? &#x1f9ac;nginx配置官方yum源&#xff1a; &#x1f9ac;nginx优点 &#x1f9ac;nginx 缺点 &#x1f9ac;查看nginx默认模块 &#x1f40c;nginx新版本的配置文件&#xff1a; &#x1f40c;nginx目录索引 &#x1f40c;nginx状态…

机器学习实战1-kNN最近邻算法

文章目录 机器学习基础机器学习的关键术语 k-近邻算法&#xff08;KNN&#xff09;准备&#xff1a;使用python导入数据实施kNN分类算法示例&#xff1a;使用kNN改进约会网站的配对效果准备数据&#xff1a;从文本文件中解析数据分析数据准备数据&#xff1a;归一化数值测试算法…

JavaWeb(9)——前端综合案例3(悬停显示下拉列表)

一、实例需求 ⌛ 实现类似百度首页的“一个简单的鼠标悬停显示的下拉列表效果”。 二、代码实现 ☕ <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>.dropdown-cont…

Flink-串讲面试题

1. 概念 有状态的流式计算框架 可以处理源源不断的实时数据&#xff0c;数据以event为单位&#xff0c;就是一条数据。 2. 开发流程 先获取执行环境env&#xff0c;然后添加source数据源&#xff0c;转换成datastream&#xff0c;然后使用各种算子进行计算&#xff0c;使用…

【数据结构OJ题】轮转数组

原题链接&#xff1a;https://leetcode.cn/problems/rotate-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 1. 方法一&#xff1a;暴力求解&#xff0c;将数组的第一个元素用临时变量tmp存起来&#xff0c;再将数组其他元素往右挪动一步&…

SpringBoot+MyBatis多数据源配置

1.先在配置文件application.yml中配置好数据源 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedb1:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rootjdbc-url: jdbc:mysql://192.168.110.128:3306/CampusHelp?useUnicodeyes&…

基于dockerfile构建sshd、httpd、nginx、tomcat、mysql、lnmp、redis镜像

一、镜像概述 Docker 镜像是Docker容器技术中的核心&#xff0c;也是应用打包构建发布的标准格式。一个完整的镜像可以支撑多个容器的运行&#xff0c;在Docker的整个使用过程中&#xff0c;进入一个已经定型的容器之后&#xff0c;就可以在容器中进行操作&#xff0c;最常见的…

【深度学习】Collage Diffusion,拼接扩散,论文,实战

论文&#xff1a;https://arxiv.org/abs/2303.00262 代码&#xff1a;https://github.com/VSAnimator/collage-diffusion 文章目录 AbstractIntroductionProblem Definition and Goals论文其他内容实战 Abstract 基于文本条件的扩散模型能够生成高质量、多样化的图像。然而&a…

CentOS 7中,配置了Oracle jdk,但是使用java -version验证时,出现的版本是OpenJDK,如何解决?

1.首先&#xff0c;检查已安装的jdk版本 sudo yum list installed | grep java2.移除、卸载圈红的系统自带的openjdk sudo yum remove java-1.7.0-openjdk.x86_64 sudo yum remove java-1.7.0-openjdk-headless.x86_64 sudo yum remove java-1.8.0-openjdk.x86_64 sudo yum r…

pytorch的CrossEntropyLoss交叉熵损失函数默认reduction是平均值

pytorch中使用nn.CrossEntropyLoss()创建出来的交叉熵损失函数计算损失默认是求平均值的&#xff0c;即多个样本输入后获取的是一个均值标量&#xff0c;而不是样本大小的向量。 net nn.Linear(4, 2) loss nn.CrossEntropyLoss() X torch.rand(10, 4) y torch.ones(10, dt…

第二篇|研究数据哪里来——建筑业

数据是研究和产业发展的重要基石&#xff0c;然而无论是学者、企业还是研究机构往往都面临着“找数据难”的局面。本期将分享一些查找建筑相关的数据及资料的渠道。希望可以帮大家解决这一难题&#xff0c;有用求收藏求收藏求收藏~ 1.政府机构 可以查找国家、地方政府的建筑行…

65 # 实现 http-server 里的 gzip 压缩

用 zlib 来实现 gzip 压缩 服务端优化都是&#xff1a;压缩 缓存 前端可以通过 webpack 插件进行压缩 gzip 根据替换来实现的&#xff0c;重复率越高&#xff0c;压缩后的结果越小 const zlib require("zlib"); const fs require("fs"); const path …