svg使用技巧

news2024/11/24 2:10:17

什么是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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python-OpenCV中的图像处理

Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种&#xff1…

ZMQ发布订阅模式二次封装

ZeroMQ 参考ZMQ从入门到掌握一 ZeroMQ是一种基于消息队列的多线程网络库&#xff0c;其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象&#xff0c;提供跨越多种传输协议的套接字。ZeroMQ 并不是一个对 socket 的封装&#xff0c;不能用它去实现已有的网络协议。它有…

加密、解密、编码

urlencode urlencode_百度百科 Base64是一种二进制到文本的编码方式&#xff0c;而且编码出的字符串只包含ASCII基础字符 下图是Base64码表&#xff0c;可以看到从0到63的每个数字都对应一个上面的一个字符。 文件-base64字符串互转 sun.misc包中的类 try (FileOutputStre…

Node.Js安装与配置教程

目录 1.下载官网 2.选择安装路径 3.添加环境变量 4.验证是否安装成功 5.修改模块下载位置 (1)查看npm默认存放位置 6.在node.js安装目录下&#xff0c;创建两个文件夹 7.修改默认文件夹 8.测试默认位置是否更改成功 9.安装报错解决办法 10.路径未更改成功解决办法 …

MIT 6.830数据库系统 -- lab six

MIT 6.830数据库系统 -- lab six 项目拉取引言steal/no-force策略redo log与undo log日志格式和检查点 开始回滚练习1&#xff1a;LogFile.rollback() 恢复练习2&#xff1a;LogFile.recover() 测试结果疑问点分析 项目拉取 原项目使用ant进行项目构建&#xff0c;我已经更改为…

【uniapp 小程序开发页面篇】代码编写规范 | 页面编写规范 | 小程序API

博主&#xff1a;_LJaXi Or 東方幻想郷 专栏&#xff1a; uni-app | 小程序开发 开发工具&#xff1a;HBuilderX 小程序开发页面篇 小程序组件规范小程序介绍小程序规范代码编写规范须遵循的开发规范 运行特性编译器选择编译规则工程目录结构static目录 使用注意static目录 条件…

Spring-2-透彻理解Spring 注解方式创建Bean--IOC

今日目标 学习使用XML配置第三方Bean 掌握纯注解开发定义Bean对象 掌握纯注解开发IOC模式 1. 第三方资源配置管理 说明&#xff1a;以管理DataSource连接池对象为例讲解第三方资源配置管理 1.1 XML管理Druid连接池(第三方Bean)对象【重点】 数据库准备 -- 创建数据库 create …

Easys Excel的表格导入(读)导出(写)-----java

一,EasyExcel官网: 可以学习一些新知识: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 二,为什么要使用easyexcle excel的一些优点和缺点 java解析excel的框架有很多 &#xff1a; poi jxl,存在问题&#xff1a;非常的消耗内存&#xff0c; easyexcel 我们…

使用TDOSCommand调用Powershell脚本对进程进行操作

列出当前运行的进程&#xff1a; varPowerShellPath, ScriptPath, CommandLine: string; beginMemo6.Clear;PowerShellPath : powershell.exe ; // 假设 PowerShell 可执行文件在系统环境变量中// 构造命令行参数CommandLine : Get-Process | Select-Object Name,Id;// 设置命…

【Linux】总结2-进程篇1

文章目录 冯诺伊曼结构操作系统什么是程序&#xff1f;什么是进程&#xff1f;操作系统是如何来管理进程的&#xff1f;PCB&#xff08;struct task_struct{...}&#xff09; 冯诺伊曼结构 冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行…

Stable Diffusion - 常用的负向提示 Embeddings 解析与 坐姿 (Sitting) 提示词

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132145248 负向 Embeddings 是用于提高 StableDiffusion 生成图像质量的技术&#xff0c;可以避免生成一些不符合预期的图像特征&#xff0c;比如…

day5gdb调试模式和makefile

一、gdb调试 1.1gdb调试的作用 gdb调试检查的是逻辑错误&#xff0c;而非语法错误 1.2gdb流程 1、gcc -g 1.c ---->加-g参数的作用&#xff0c;生成可以调试的gdb文件 2、gdb 可执行文件名/a.out ---->进入gdb工具进行调试 3、输入l&#xff0c;带行号打印文件信息…

管理类联考——逻辑——论证逻辑——汇总篇——目录+提炼

文章目录 一、削弱方法关系的削弱必要方法的削弱因果推理的削弱果因推理的削弱概念跳跃的削弱数量比例的削弱比例因果的削弱 二、支持方法关系的支持必要方法的支持因果推理的支持果因推理的支持概念跳跃的支持数量比例的支持比例因果的支持 三、假设方法关系的假设必要方法的假…

不分股权不分管理,只分利润:共享模式的新零售布局

实体行业如何通过共享模式去整合那些有资源的人&#xff0c;来完成新零售的一个布局&#xff1f;比如对于餐饮行业而言&#xff0c;一样的资源&#xff0c;经常有用餐、聚餐需求的人是谁&#xff1f; 有商会组织者、公司的管理层、培训机构、社群群主等等。那么如何把这些人整…

记一次Linux启动Mysql异常解决

文章目录 第一步&#xff1a; netstat -ntlp 查看端口情况2、启动Mysql3、查看MySQL日志 tail -100f /var/log/mysqld.log4、查看磁盘占用情况&#xff1a;df -h5、思路小结 第一步&#xff1a; netstat -ntlp 查看端口情况 并没有发现3306数据库端口 2、启动Mysql service …

【Windows】Windows11系统用户自己添加开机启动项的方法

按win R快捷键&#xff0c;打开运行窗口&#xff0c;在输入框中输入shell:startup后点击运行&#xff0c;打开启动文件夹&#xff1a; 把想增加的开机启动软件的快捷方式图标拖入到该文件夹中&#xff0c;如下图所示&#xff1a; 按ctrl shift esc打开任务管理器&#xff0c…

UWB伪应用场景 - 别再被商家忽悠

近几年UWB技术在网上宣传得如火如荼&#xff0c;与高精度定位几乎或等号&#xff0c;笔者认为这是营销界上的一大成功案例。 UWB超宽带技术凭借着低功耗、高精度&#xff0c;确实在物联网行业混得风生水起&#xff0c;但在无数实际应用案例中&#xff0c;根据客户的反馈情况&a…

python小游戏代码200行左右,python小游戏代码1000行

大家好&#xff0c;小编为大家解答20行python代码的入门级小游戏的问题。很多人还不知道python小游戏代码200行左右&#xff0c;现在让我们一起来看看吧&#xff01; 大家小时候都玩过贪吃蛇吧&#xff1f;小编小时候可喜欢拿爸妈的手机玩了&#xff0c;厉害着呢&#xff01;今…

Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

今日目标 掌握纯注解开发依赖注入(DI)模式 学习使用纯注解进行第三方Bean注入 1 注解开发依赖注入(DI)【重点】 问题导入 思考:如何使用注解方式将Bean对象注入到类中 1.1 使用Autowired注解开启自动装配模式&#xff08;按类型&#xff09; Service public class StudentS…

redis基础(三十六)

安装redis、配置redis 目录 一、 概述 &#xff08;一&#xff09;NoSQL 1、类型 2、应用场景 &#xff08;二&#xff09;Redis 二、安装 &#xff08;一&#xff09;编译安装 &#xff08;二&#xff09;RPM安装 三、目录结构 四、命令解析 五、redis登录更改 1、…