热门标签 | 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图标加载动画。这些动画不仅视觉效果出色,还能提升用户体验。通过本文,您可以了解如何在项目中应用这些动画。 ... [详细]
  • CSS3 @font-face 字体应用技术解析与实践
    在Web前端开发中,HTML教程和CSS3的结合使得网页设计更加多样化。长期以来,Web设计师受限于“web-safe”字体的选择。然而,CSS3中的`@font-face`规则允许从服务器端加载自定义字体,极大地丰富了网页的视觉效果。通过这一技术,设计师可以自由选择和使用各种字体,提升用户体验和页面美观度。本文将深入解析`@font-face`的实现原理,并提供实际应用案例,帮助开发者更好地掌握这一强大工具。 ... [详细]
  • Android 实战进阶:自定义形状的ImageView——CustomShapeImageView深入解析与应用
    原文:Android项目实战(九):CustomShapeImageView自定义形状的ImageView一个两年前出来的第三方类库,具有不限于圆形Im ... [详细]
  • Leetcode学习成长记:天池leetcode基础训练营Task01数组
    前言这是本人第一次参加由Datawhale举办的组队学习活动,这个活动每月一次,之前也一直关注,但未亲身参与过,这次看到活动 ... [详细]
  • TypeScript ESLint: 避免使用隐式 any 类型,建议指定更具体的类型以提高代码可维护性
    在使用 Vue 引入 SVGSpriteLoader 时遇到了问题。具体表现为在 `shims-vue.d.ts` 文件中进行相关配置后,WebStorm 报错。为了解决这一问题,建议避免使用隐式 `any` 类型,而是指定更具体的类型,以提高代码的可维护性和类型安全性。可以通过在 ESLint 配置中禁用隐式 `any` 类型来实现这一目标。 ... [详细]
  • a16z深入解析:代币设计的常见误区、优化策略及未来趋势分析
    a16z深入解析:代币设计的常见误区、优化策略及未来趋势分析 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
  • Go 项目中数据库配置文件的优化与应用 ... [详细]
  • 在 Vue 3 项目中使用 ElementPlus 的 Icon 组件时,遇到了 SVG 图标无法正常显示的问题。经过查阅官方文档和 GitHub 讨论,最终发现是由于图标路径配置不正确导致的。通过调整图标路径和引入方式,成功解决了这一问题,并确保了图标能够正确加载和显示。此外,还对项目依赖进行了更新,以兼容最新的 ElementPlus 版本。 ... [详细]
  • PyQt5 QTextEdit:深入解析Python中多功能GUI库的应用与实现
    本文详细探讨了 PyQt5 中 QTextEdit 组件在 Python 多功能 GUI 库中的应用与实现。PyQt5 是 Qt 框架的 Python 绑定,提供了超过 620 个类和 6000 个函数及方法,广泛应用于跨平台应用程序开发。QTextEdit 作为其中的重要组件,支持丰富的文本编辑功能,如富文本格式、文本高亮和自定义样式等。PyQt5 的流行性不仅在于其强大的功能,还在于其易用性和灵活性,使其成为开发复杂用户界面的理想选择。 ... [详细]
  • 深入RTOS实践,面对原子操作提问竟感困惑
    在实时操作系统(RTOS)的实践中,尽管已经积累了丰富的经验,但在面对原子操作的具体问题时,仍感到困惑。本文将深入探讨RTOS中的原子操作机制,分析其在多任务环境下的重要性和实现方式,并结合实际案例解析常见的问题及解决方案,帮助读者更好地理解和应用这一关键技术。 ... [详细]
  • 如何在服务器上正确连接显示器与键盘?一台主机是否能够支持双显示器及键盘配置?通常情况下,一台主机确实可以连接两个显示器和键盘,但需要使用适当的连接设备,如KVM切换器或分屏器。只要主机的硬件配置足够,这种多显示器配置是完全可行的。理论上,通过合适的设备,最多可以实现一拖五的配置。具体的技术参数和连接方法将在下文中详细说明。 ... [详细]
  • 在Vite项目优化过程中,通过使用rollup-plugin-visualizer插件,可以有效地对Rollup打包结果进行可视化分析,帮助开发者清晰地了解各个模块的占用情况,从而进行更有针对性的优化。此外,结合其他常用插件,如vite-plugin-compression和vite-plugin-inspect,可以进一步提升项目的性能和可维护性。 ... [详细]
  • 注:写博客或者项目的README文档经常用到markdown语法,所以markdown的语法做了一个总结,本文是基于【markdown】基 ... [详细]
  • 手动将 Webpack 2.x 迁移到最新版 Webpack 4.8.3(当前 GitHub 最新版本)
    手动webpack2.x升级到webpack4.8.3(当前github最新版本)一直使用的webpack是2.3.3版本作为生产环境使用,看了react-create- ... [详细]
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社区 版权所有