的第一个月份,希望能多记录一些实用的东西吧,今天来分享一下Android中的矢量图(SVG)的用法,我首先会说一下矢量图的基本使用方法,然后说一下阿里巴巴矢量图标库Iconfont的使用,最后会通过一个开源库的学习来自定义自己的矢量图标库,你可以把它集成到自己的项目框架中去,方便以后自己在自己的项目中扩展,这在搭建基础项目框架中都是能用到的,也可以丰富自己的技术栈的整合。好了,废话不多说了,说干就干吧!
一、在Android中使用SVG矢量图
理论知识说明:Google在Android 5.X中提供了两个新API来帮助支持SVG: 1、 VectorDrawable(显示SVG图标) 2、AnimatedVectorDrawable(SVG动画)
1、什么是SVG?
SVG (Scalable Vector Graphics, 可伸缩矢量图形) 是W3C 推出的一种开放标准的文本式矢量图形描述语言,他是基于XML的、专门为网络而设计的图像格式,SVG是一种采用XML来描述二维图形的语言,所以它可以直接打开xml文件来修改和编辑。
2、矢量图有哪些优点?
矢量图是用点和线来描述图形,所以文件会比较小,同时也能提供高清晰的画面矢量图缩放自由且不会失真,完全适配于任何分辨率的屏幕矢量图的是以xml语言来描述的,所以它修改自如矢量图色彩分辨率非常高清,同时支持滤镜跨平台,因为矢量图是纯文本格式来描述的,所以不受平台的限制
3、Path的介绍:
M = moveto(M X,Y) :将画笔移动到指定的坐标位置
L = lineto(L X,Y) :画直线到指定的坐标位置
H = horizontal lineto(H X):画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝赛曲线
S = smooth curveto(S X2,Y2,ENDX,ENDY):三次贝赛曲线
Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝赛曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射前面路径后的终点
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
Z = closepath():关闭路径
说明一点,我的数学知识菜的不想多提,所以这些东西我是真不懂,大家有兴趣的可以自己去研究一下,牛逼的人你想画什么就能画什么。
4、具体使用步骤:
1、我这里新建一个工程SVGDemo,然后我们在drawable文件夹下右键新建Vector Asset文件,如图所示:
2、然后会弹出一个对话框,这里可以创建我们的svg图标,默认选中的类型是Google的Material类型,图标是安卓机器人,我们可以点击Icon图标选择自己想要的,如果你本地有你需要使用的矢量图,你可以选择Local file类型,选择制作你自己想要的矢量图,如图所示:
3、创建完成后,我们可以发现drawable目录下生成了一个新的xml文件,这个就是我们的矢量图文件,可以看到是通过path去定义路径,然后内部使用上面介绍的api进行路径的描绘来实现的矢量图标,我这里选择了一个返回按钮,如图所示:
这里需要说明的是,Android官方虽然给我们提供了很多矢量图标,但是在实际开发中我们一般都不会去使用的,因为它太丑了!那我们该如何获取矢量图呢?很简单,你可以直接找你们公司的UI妹子让她给你提供,或者你又不想撩妹的,你可以去阿里巴巴矢量图标库中下载,里面有各种各样好看的图标,基本能满足你的日常需求,这里随便截取了一张图给大家看一下,三种类型的图标随你选择:
4、创建完成之后,我们来看如何使用?基本使用方式:我在MainActivity的布局文件中放置了一个TextView,然后把这个图标引入进去,如图所示:
可以看到,通过上面这几个步骤,我们就可以使用我们的矢量图了,那看到这里不知道大家有没有发现一个问题呢?如果我想再添加一个这样的返回按钮并且不是绿色的我想要红色的,那这个时候怎么办呢?有人会说了:再复制出一个xml文件,把颜色改成红色的不就好了。对,这位大哥,你说的对,你开心就好,那照这个逻辑,我想要一个全系列颜色的,我得复制多少个文件啊,显而易见太麻烦了,此种方式不可取,那我们该怎么办呢?其实解决的方式很简单,我们需要把这些图标制作成字体,合成在一个字体文件里面,然后调用字体里面的一些字符串进行显示就行了。
二、在Android中使用Iconfont图标
(一)理论基础——使用步骤总结:
1: 从iconfont平台选择要使用到的图标,并下载至本地;复制字体文件到项目 assets 目录;
2: 打开下载下来的文件,并在目录中打开demo.html,找到图标相对应的 HTML 实体字符码
3: 打开 res/values/strings.xml,添加 string 值;
<string name="icons">㘅 㖭 㖮 㖯</string>
4:打开 activity_main.xml,添加 string 值到 TextView:
<TextView
android:id="@+id/like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/icons" />
5:为 TextView 指定文字:
import android.graphics.Typeface;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Typeface iconfont = Typeface.createFromAsset(getAssets(), "iconfont/iconfont.ttf");
TextView textview = (TextView)findViewById(R.id.like);
textview.setTypeface(iconfont);
}
(二)具体操作步骤:
1、这一步就是下载文件,我这里使用一张动态图来进行说明:
然后我们打开下载的文件,将iconfont.ttf文件复制到assets目录下。
2、打开下载文件中的demo_unicode.html文件,然后将需要使用的图标的unicode编码放到values的strings文件中,我这里选择了购物车和删除图标,如下所示:
<string name="svg_cart"></string><string name="svg_delete"></string>
3、然后我们在xml文件中新增一个TextView控件,文本内容引用购物车这个文本,代码如下:
<TextViewandroid:id="@+id/tv_cart"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="50sp"android:textColor="@color/colorAccent"android:text="@string/svg_cart" />
4、在Activity中绑定控件,使用Typeface类设置文本,代码如下:
TextView textView = (TextView) findViewById(R.id.tv_cart);Typeface typeface = Typeface.createFromAsset(getAssets(),"iconfont.ttf");textView.setTypeface(typeface);
5、最后运行的效果图如下,可以看到购物车图标完美的被加载出来了:
三、使用Iconfont制作自己的字体图标库
需要说明的是,这里是基于GitHub上的一个开源库进行设计的,我们需要在项目中引入它的核心模块,它所提供的字体模块你可以不引用,因为这里是制作自己的字体库。
项目地址:/mikepenz/Android-Iconics
大家可以先去大体浏览一些这个库的内容,然后再接着往下看如何自定义字体图标库。
1、首先在我们本地的项目中添加核心依赖:
compile "com.mikepenz:iconics-core:2.8.1@aar"
2、新建一个类MyIconFont,实现这个库中的ITypeface接口,或者你可以直接copy这个库中的CustomFont类然后进行修改,CustomFont类在app包下,大家可以点击去看看,我这里还继续上一小节中的下载的字体进行制作,如下所示:
首先来看图标库中的代码,代码中都添加了注释,也比较简单:
package com.jarchie.svg;import android.content.Context;import android.graphics.Typeface;import com.mikepenz.iconics.typeface.IIcon;import com.mikepenz.iconics.typeface.ITypeface;import java.util.Collection;import java.util.HashMap;import java.util.LinkedList;/*** Created by Jarchie on \1\12.* 自定义字体图标库*/@SuppressWarnings("WeakerAccess")public class MyIconFont implements ITypeface{private static final String TTF_FILE = "iconfont.ttf"; //字体名称private static Typeface typeface = null;private static HashMap<String, Character> mChars;@Overridepublic IIcon getIcon(String key) { //通过key拿到内部类中的Iconreturn Icon.valueOf(key);}@Overridepublic HashMap<String, Character> getCharacters() { //将字符串存到HashMap中if (mChars == null) {HashMap<String, Character> aChars = new HashMap<>();for (Icon v : Icon.values()) {aChars.put(v.name(), v.character); //字符串的名字和值put进去,一一对应}mChars = aChars;}return mChars;}@Overridepublic String getMappingPrefix() { //这个是Icon类中你自己定义的字体的前缀,一定不能搞错,否则找不到对应的字体return "archie";}@Overridepublic String getFontName() { //字体名字,可以随便写return "JarchieFont";}@Overridepublic String getVersion() { //版本号return "1.0.0";}@Overridepublic int getIconCount() { //字体数量return mChars.size();}@Overridepublic Collection<String> getIcons() { //返回一个有序集合Collection<String> icons = new LinkedList<>();for (Icon value : Icon.values()) {icons.add(value.name());}return icons;}@Overridepublic String getAuthor() { //作者return "Jarchie";}@Overridepublic String getUrl() { //域名URL,可以随便写,也可不写return "/JArchie/SVGDemo";}@Overridepublic String getDescription() { //描述内容return "The custom icon font for Iconics";}@Overridepublic String getLicense() { //授权return "XXX Licensed";}@Overridepublic String getLicenseUrl() { //授权地址return "/JArchie/SVGDemo";}@Overridepublic Typeface getTypeface(Context context) { //获取Typeface对象if (typeface == null) {try {typeface = Typeface.createFromAsset(context.getAssets(), TTF_FILE);} catch (Exception e) {return null;}}return typeface;}@SuppressWarnings({"WeakerAccess", "unused"})public enum Icon implements IIcon {archie_all('\ue696'),archie_back('\ue697'),archie_cart('\ue698'),archie_category('\ue699'),archie_close('\ue69a'),archie_comments('\ue69b'),archie_cry('\ue69c'),archie_delete('\ue69d'),archie_edit('\ue69e'),archie_form('\ue6a2'),archie_qrcoed('\ue6a9'),archie_search('\ue6ac'),archie_selected('\ue6ad'),archie_set('\ue6ae'),archie_success('\ue6b1');char character;Icon(char character) {this.character = character;}public String getFormattedName() {return "{" + name() + "}";}public char getCharacter() {return character;}public String getName() {return name();}// remember the typeface so we can use it laterprivate static ITypeface typeface;public ITypeface getTypeface() {if (typeface == null) {typeface = new MyIconFont();}return typeface;}}}
这里需要注意的是,在代码中转换unicode字符的时候,需要将“&#x”替换为“\u”。
3、自定义我们的Application,这在开源库中有说明,具体代码为:
package com.jarchie.svg;import android.app.Application;import com.mikepenz.iconics.Iconics;/*** Created by Jarchie on \1\12.* 自定义Application*/public class BaseApp extends Application {@Overridepublic void onCreate() {super.onCreate();//only required if you add a custom or generic font on your ownIconics.init(this);//register custom fonts like this (or also provide a font definition file)Iconics.registerFont(new MyIconFont());}}
4、具体使用,测试是否正常显示:
这里我在xml文件中新增了一个ImageView和一个TextView,然后通过使用我们自己的字体图标库来为它们设置内容,代码如下:
<ImageViewandroid:id="@+id/iv_set"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/tv_qrcode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"/>
ImageView imageView = (ImageView) findViewById(R.id.iv_set);TextView textView1 = (TextView) findViewById(R.id.tv_qrcode);imageView.setImageDrawable(new IconicsDrawable(this).icon(MyIconFont.Icon.archie_set).color(Color.BLUE).sizeDp(50));textView1.setBackground(new IconicsDrawable(this).icon(MyIconFont.Icon.archie_qrcoed).sizeDp(50));
5、最后实现的效果为:
四、遇到的问题
自定义的图标库无法在xml中引用,使其显示,不知道是因为研究的不够还是这个库本身的BUG,在后续的学习中我会继续跟进这个问题。
案例源码地址:/JArchie/SVGDemo
好了,本篇要分享的东西就是这么多,欢迎大家留言探讨,多多批评指正!