热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Android使用矢量图(SVG,VectorDrawable)实践篇

前言本文是以读者对SVG有一定了解为前提的,否则请先百(谷)度(歌)了解下。实践都是从坑里爬出来的,因此本文的子题目也可叫做Android使用矢量图填坑记。文章开始前,先墙裂安利一个网站,阿里的ico
前言

本文是以读者对SVG有一定了解为前提的,否则请先百(谷)度(歌)了解下。

实践都是从坑里爬出来的,因此本文的子题目也可叫做Android使用矢量图填坑记。

文章开始前,先墙裂安利一个网站,阿里的iconfont,海量在线矢量图,早收藏早致富。本文主要涉及到的矢量图资源均来自该网站。放图镇楼:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">

<path
android:fillColor="#ffffff"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>

vector>

基本属性说明:

  • width, height:图片的宽高。可手动修改到需要尺寸;
  • viewportHeight, viewportWidth:对应将上面heightwidth等分的份数。以svg_ic_arrow_right.xml举例,可以想象将长宽都为8dp的正方形均分为24x24的网格,在这个网格中就可以很方便地描述点的坐标,图像就是这些点连接起来构成的。
  • fillColor:填充颜色。最好直接在这里写明色值#xxxxxxxx,而不要用@color/some_color的形式,避免某些5.0以下机型可能会报错。
  • pathData:在2中描述的网格中作画的路径。具体语法不是本文的重点,故不展开。

这段代码描述出来的是一个白色箭头,可以从Android Studio的preview功能栏里预览到它的样子:

android{
...
defaultConfig {
...
vectorDrawables.useSupportLibrary = true
}
...
}
dependencies {
...
compile "com.android.support:appcompat-v7:21+" // 至少Api21
...
}

项目的Activity中都包含(通用做法是在BaseActivity中加):

static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

AppCompatImageView

这是继承自ImageView用于5.0以下加载矢量图的控件,只需要替换srcsrcCompat属性,其它没什么不同。例如:

<android.support.v7.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/svg_ic_arrow_right"/>
  • 如果你的Activity直接或间接继承自AppCompatActivity,当前视图中的ImageView在编译过程中会被自动转为AppCompatImageView(support包中所有含有AppCompat前缀的控件均受相同处理),因而在Activity中通过findViewById()的实例用ImageViewAppCompatActivity接收是没有区别的。
  • 用以上条件的Activity中装载的Fragment,或者通过动态注入(如DialogcontentView)的ImageView,均将被自动转为AppCompatActivity
  • 从xml文件中初始化ImageView并加载矢量图,必须使用AppCompatImageViewsrcCompat属性。
  • ImageView的染色属性tint同样适合矢量图。

TextView

在我的经验中,TextView可以用到矢量图的场景是最多的,主要是设置CompoundDrawable。例如:

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableRight="@drawable/svg_ic_arrow_right"
android:drawablePadding="4dp"
android:text="drawable right"/>

这样设置后,没有任何不适,编译器也不报错,可能你自己运行也没问题。但是!这才是深坑啊。5.0以下某些机型可能会崩溃的。

AppCompatTextView是没有对CompoundDrawable进行适配的,所以需要自己动手才能丰衣足食。简单原理是,判断系统版本如果小于5.0,就用ContextCompat.getDrawable获取到Drawable实例,再setCompoundDrawablesWithIntrinsicBounds

这个部分本人已经做好并开源了,地址:VectorCompatTextView,轻松compile到项目中使用。还特意添加了一个实用功能——tint染色——可以选择是否让图标与文字颜色一样,这样就不必关心xml里的fillColor属性了。用例:

<com.xw.repo.VectorCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_gray_light"
android:gravity="center_vertical"
android:padding="16dp"
android:text="Next"
android:textSize="16sp"
app:drawableRightCompat="@drawable/svg_ic_arrow_right"
app:tintDrawableInTextColor="true"/>

效果:


Tips:
存在这样一种情形,连续两个控件(编号1和2)都来加载同一张svg图,svg的本来颜色是A,控件1将颜色改为了B,控件2也加载这张svg,颜色却变为了B,这应该是Android系统对矢量图的缓存造成的。解决办法是把svg的本来颜色改为B,控件2再改为颜色A。(好绕,不过一般不会遇到)

MenuItem

MenuItem就是在res/menu/目录下通过xml配置的菜单,适用于NavigationViewmenu属性和ActivityonCreateOptionsMenu()注入的选项菜单。

前一阵做了一个小应用叫“简影讯”,发现MenuItem是可以完美支持矢量图的,而且也可以自动跟随文字颜色改变颜色。且看证明:



自适应颜色

简影讯(开源地址:GracefulMovies),是一枚基于Retrofit+RxJava+MVP+Colorful多彩主题框架开发的高颜值影讯app。简约,优雅,精彩,即看即走。欢迎在应用宝或360手机助手下载围观。
该项目除ic_launcher外,所有的图标都是矢量图。
“是时候全面使用矢量图了。”

VectorDrawable 转 Bitmap

自定义View中也可以自由使用矢量图。
首先需要将VectorDrawable 转为 Bitmap,看码:

public Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (Build.VERSION.SDK_INT drawable = (DrawableCompat.wrap(drawable)).mutate();
}

Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);

return bitmap;
}

执行以上方法获得一个Bitmap的实例(设为mVectorBitmap),然后再在ondraw()里根据你的需求画出bitmap:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
///
canvas.drawBitmap(mVectorBitmap, left, top, paint);
///
}

后记

矢量图的优点一大把,但也不是万能的。矢量图特别适合icon图标的应用场景,但是不能用于比如加载相册时,设置的placeholder或者error这类需要频繁切换回收的应用场景,否则会造成非常明显的卡顿,因为矢量图是不被硬件加速支持的。

Android 5.0推出已经有些年份了,也不知道Android开发圈对矢量图的使用情况,但知道比如微信这些大厂早已全面推广使用。然而在本人周边似乎自己算先驱了,所以才有了把过程中的一些经验总结分享出来的想法。

毕竟本人才疏学浅,难免有纰漏之处,请大神轻拍砖,并不吝赐教。若对后来学习者有帮助,那花这一天码的字自然也超值了,希望共勉。


转载自:
作者:woxingxiao
链接:http://www.jianshu.com/p/0555b8c1d26a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

推荐阅读
  • 本文介绍了一种使用CSS3和jQuery实现的35款SVG图标加载动画。这些动画不仅视觉效果出色,还能提升用户体验。通过本文,您可以了解如何在项目中应用这些动画。 ... [详细]
  • 在开发H5页面时,为了减少资源请求和简化工作流程,直接使用SVG和CSS3来创建简单的图形元素是一个高效的选择。本文将探讨如何不依赖于第三方图标库,仅通过HTML和CSS技术实现一个‘返回顶部’的图标。 ... [详细]
  • 如何高效创建和使用字体图标
    在Web和移动开发中,为什么选择字体图标?主要原因是其卓越的性能,可以显著减少HTTP请求并优化页面加载速度。本文详细介绍了从设计到应用的字体图标制作流程,并提供了专业建议。 ... [详细]
  • 深入解析:FlameGraph 火焰图在性能分析中的应用
    本文详细介绍了 FlameGraph 火焰图作为性能分析工具的原理、使用方法及其应用场景,帮助开发者更好地理解和利用这一强大的可视化工具。 ... [详细]
  • List & Label 19现已发布,此版本引入了报表参数、集合变量、扩展区域以及交互式排序等功能,并增加了对OData和REST数据提供器的支持,同时推出了包括组合图、堆叠图、漏斗图等在内的新型图表。 ... [详细]
  • 本文探讨了如何使SVG图形在不同设备上实现自适应显示,特别是在移动设备上的应用。 ... [详细]
  • SVG画布HTML5提供两种强有力的“画布”:SVG和Canvas。SVG的特点:SVG绘制的是矢量图,因此对图像进行放大不会失真基于XM ... [详细]
  • 动画队列的设计目的是为了确保一系列任务能够按照预定顺序执行,每个任务只有在其前一个任务完成后才开始。这些任务既可以是同步的,也可以是异步的。本文将探讨jQuery动画系统中的队列机制,并介绍如何使用队列来优化动画效果。 ... [详细]
  • SVG 动态滤镜实现水面波动效果
    探讨如何使用SVG滤镜技术创建动态的水面波动效果,包括HTML、CSS和JavaScript代码示例。 ... [详细]
  • 此模板采用Bootstrap4构建,适用于多种场景,如作品集展示、个人简历制作及工作室业务介绍等。该多功能机构与项目模板包含10种不同的首页设计。 ... [详细]
  • 经过一段时间的学习与实践,我已经使用D3.js完成了一些项目。鉴于中文D3教程稀缺,而英文资料虽丰富却对英语水平有一定要求,特此撰写一系列D3实战文章,旨在通过具体案例(如统计数据可视化、地图信息展示等)分享D3的使用技巧,促进技术交流。 ... [详细]
  • 作为一名CSS初学者,我在博客园中尝试通过CSS美化页面,特别是为超链接添加图标,以提升阅读体验。本文将分享如何使用CSS和字体图标库来实现这一功能。 ... [详细]
  • 本文详细介绍了如何在VSCode环境中配置Prettier工具以支持TypeScript项目,同时结合ESLint实现代码风格的一致性和自动化格式化。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 本文介绍如何在Inkscape中将SVG格式的彩色图像转换为灰度图像,包括具体的操作步骤和RGB到灰度的标准转换公式。 ... [详细]
author-avatar
青峰的兔子饭团
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有