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">
  <path
      android: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">
  <path
      android: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>

在布局中引用

<ImageView
    android: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图片的颜色。

<ImageView
    android: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来控制颜色变化

<ImageView
    android: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.AppCompatImageView
    android: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">
        <vector
            android:name="heartbreak"
            android:width="56dp"
            android:height="56dp"
            android:viewportWidth="56"
            android:viewportHeight="56">
            <group
                android:name="broken_heart_left_group"
                android:pivotX="28"
                android:pivotY="37.3">
                <path
                    android: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">
            <objectAnimator
                android: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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS应用开发的新机遇与挑战

HarmonyOS 4已经于2023年8月4日在HDC2023大会上正式官宣。对广大HarmonyOS开发者而言&#xff0c;这次一次盛大的大会。截至目前&#xff0c;鸿蒙生态设备已达7亿台&#xff0c;HarmonyOS开发者人数超过220万。鸿蒙生态充满着新机遇&#xff0c;也必将带来新的挑战。 HarmonyO…

探析STM32标准库与HAL库之间的差异与优劣

引言&#xff1a; 在嵌入式开发领域&#xff0c;STMicroelectronics的STM32系列芯片广受欢迎。STM32提供了两种主要的软件库&#xff0c;即标准库和HAL库&#xff0c;用于开发各种应用。本文将探讨这两种库之间的差异&#xff0c;比较它们的优劣&#xff0c;并分析在选择库时需…

MFC计算分贝

分贝的一种定义是&#xff0c;表示功率量之比的一种单位&#xff0c;等于功率强度之比的常用对数的10倍&#xff1b; 主要用于度量声音强度&#xff0c;常用dB表示&#xff1b; 其计算&#xff0c;摘录网上一段资料&#xff1b; 声音的分贝值可以通过以下公式计算&#xff1…

用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项

一、实际工作中需要对转换选项细化内容 在昨天我们实现了最简单的半角字符和全角字符相互转换功能&#xff0c;就是将英文字母、阿拉伯数字、标点符号、空格全部进行转换。 在实际工作中&#xff0c;我们有时只想英文字母、阿拉伯数字、标点符号、空格之中的一两类进行转换&a…

TDengine + Telegraf + Grafana 实现图形化服务器状态监控

TDengine Telegraf Grafana 实现图形化服务器状态监控 技术栈环境搭建安装tdenginue下载安装包解压文件运行安装文件启动td运行 taosAdapter 安装Telegraf添加yum源安装生成配置文件修改配置文件启动telegraf 安装Grafana直接yum安装安装td数据源配置启动Grafana配置数据源导…

【论文阅读】基于深度学习的时序异常检测——TransAD

系列文章链接 数据基础&#xff1a;多维时序数据集简介 论文一&#xff1a;2022 Anomaly Transformer&#xff1a;异常分数预测 论文二&#xff1a;2022 TransAD&#xff1a;异常分数预测 论文链接&#xff1a;TransAD.pdf 代码库链接&#xff1a;https://github.com/imperial…

节能延寿:ARM Cortex-M微控制器下的低功耗定时器应用

嵌入式系统的开发在现代科技中发挥着至关重要的作用。它们被广泛应用于从智能家居到工业自动化的各种领域。在本文中,我们将聚焦于使用ARM Cortex-M系列微控制器实现低功耗定时器的应用。我们将详细介绍在嵌入式系统中如何实现低功耗的定时器功能,并附上代码示例。 嵌入式系…

面试热题(最长上升子序列)

给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 输入&#xff1…

Zebec Protocol ,不止于 Web3 世界的 “Paypal”

Paypal是传统支付领域的巨头企业&#xff0c;在北美支付市场占有率约为77%以上。从具体的业务数据看&#xff0c;在8月初&#xff0c;Paypal公布的2023年第二季度财报显示&#xff0c;PayPal第二季度净营收为73亿美元&#xff0c;净利润为10.29亿美元。虽然Paypal的净利润相交去…

Docker容器监控(Cadvisor +Prometheus+Grafana)

环境部署&#xff0c;接着上一篇文章Docker容器部署&#xff08;Cadvisor InfluxDBGrafana&#xff09;开始 目录 1、先清理一下容器 2、部署Cadvisor 3、访问Cadvisor页面 4、部署Prometheus 5、准备配置 6、运行prometheus容器 7、访问prometheus页面 8、部署Grafan…

Element-ui中分页器的使用

<template>中写&#xff1a; js中写&#xff1a;

鉴源实验室丨汽车网络安全运营

作者 | 苏少博 上海控安可信软件创新研究院汽车网络安全组 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 01 概 述 1.1 背景 随着车辆技术的不断进步和智能化水平的提升&#xff0c;车辆行业正经历着快速的变革和技术进步。智能化…

docker小白第一天

docker小白第一天 docker是什么docker理念容器与虚拟机比较docker能干什么docker官网介绍docker的基本组成docker平台架构 docker是什么 系统平滑移植&#xff0c;容器虚拟化技术。即源代码配置环境版本&#xff0c;打个包形成一个镜像文件&#xff0c;即软件带环境一起安装&a…

jmeter工具测试和压测websocket协议【杭州多测师_王sir】

一、安装JDK配置好环境变量&#xff0c;安装好jmeter 二、下载WebSocketSampler发送请求用的&#xff0c;地址&#xff1a;https://bitbucket.org/pjtr/jmeter-websocket-samplers/downloads/?spma2c4g.11186623.2.15.363f211bH03KeI 下载解压后的jar包放到D:\JMeter\apache-j…

python接口自动化之使用requests库发送http请求

​ requests库 ​ 什么是Requests &#xff1f;Requests 是⽤Python语⾔编写&#xff0c;基于urllib&#xff0c;采⽤Apache2 Licensed开源协议的 HTTP 库。它⽐ urllib 更加⽅便&#xff0c;可以节约我们⼤量的⼯作&#xff0c;完全满⾜HTTP测试需求。 ​ 安装&#xff1a;cm…

代码随想录算法训练营之JAVA|第二十四天| 93. 复原 IP 地址

今天是第24天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 93. 复原 IP 地址https://leetcode.cn/problems/restore-ip-addresses/ 第一想法 题目理解&#xff1a;将一串数字字符串变成正确的ip格式的字符串。 这类题目是切分字符串&#xff0c;ip一…

中介者模式(Mediator)

中介者模式是一种行为设计模式&#xff0c;可以减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互&#xff0c;迫使它们通过一个封装了对象间交互行为的中介者对象来进行合作&#xff0c;从而使对象间耦合松散&#xff0c;并可独立地改变它们之间的交互。中介者…

【项目部署】JavaScript解析JSON解析报错Unexpected token xxx is not valid JSON

问题背景 这个报错发生在之前部署的一个前后端分离的项目中。后端使用的Spring Boot&#xff0c;前端使用的JavaScript&#xff0c;前后端交互使用Thymeleaf框架。 现象 项目组的另一个小伙伴说&#xff0c;突然有个页面打不开了&#xff0c;整个页面全空白。我F12打开浏览器…

玩转graphQL

转载至酒仙桥的玩转graphQL - SecPulse.COM | 安全脉搏 前言 在测试中我发现了很多网站开始使用GraphQL技术&#xff0c;并且在测试中发现了其使用过程中存在的问题&#xff0c;那么&#xff0c;到底GraphQL是什么呢&#xff1f;了解了GraphQL后能帮助我们在渗透测试中发现哪些…

Jwt(Json web token)——使用token的权限验证方法 用户+角色+权限表设计 SpringBoot项目应用

目录 引出使用token的权限验证方法流程 用户、角色、权限表设计权限表角色表角色-权限关联表用户表查询用户的权限&#xff08;四表联查&#xff09;数据库的视图 项目中的应用自定义注解拦截器controller层DTO返回给前端枚举类型的json化日期json问题 实体类-DAO 总结 引出 1.…