Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android 自定义 svg 颜色

Android 自定义 svg 颜色

作者头像
stormKid
发布于 2018-10-18 03:41:33
发布于 2018-10-18 03:41:33
2.2K00
代码可运行
举报
文章被收录于专栏:计算机编程计算机编程
运行总次数:0
代码可运行

1、XML 设定颜色

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  <vector android:height="24dp" android:viewportHeight="1024"
    android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FFF" android:pathData="M395.22,513.6l323.14,-312.37c19.05,-18.42 19.05,-48.27 0,-66.66 -19.05,-18.42 -49.91,-18.42 -68.96,0L291.75,480.29c-19.05,18.42 -19.05,48.27 0,66.66l357.63,345.69c9.53,9.21 22.01,13.8 34.5,13.8 12.49,0 24.97,-4.59 34.47,-13.83 19.05,-18.42 19.05,-48.24 0,-66.66L395.22,513.6z"/>
  </vector>

xml设定颜色很简单,fillColor 这个attr即可设定。

2、kotlin代码动态设定颜色

先构造一个适用的对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * svg 图片需要构建的对象
 */
data class InitImgRes(
        @DrawableRes val imgRes: Int,
        @ColorRes val colorRes: Int,
        val imageView: ImageView,
        val context: Context
)

一般很多博客是这样写的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   /**
     * 给imageView 的svg初始化颜色
     */
    fun initSvgColor(initImgRes: InitImgRes){
        // 获取该image的资源
        val res  = initImgRes.context.resources
        // 获取该image的主题对象
        val theme = initImgRes.context.theme
        //创造vectorDrawable工具对象,影响vectorView绘制
        val vectorDrawableCompat = VectorDrawableCompat.create(res,initImgRes.imgRes,theme) ?: return
        // 使用Tint上色
        if (Build.VERSION.SDK_INT>22)
        vectorDrawableCompat.setTint(res.getColor(initImgRes.colorRes,theme))
        else vectorDrawableCompat.setTint(res.getColor(initImgRes.colorRes))
        initImgRes.imageView.setImageDrawable(vectorDrawableCompat)
    }

VectorDrawableCompat create源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   @Nullable
    public static VectorDrawableCompat create(@NonNull Resources res, @DrawableRes int resId, @Nullable Theme theme) {
        if (VERSION.SDK_INT >= 24) {
            VectorDrawableCompat drawable = new VectorDrawableCompat();
            drawable.mDelegateDrawable = ResourcesCompat.getDrawable(res, resId, theme);
            drawable.mCachedConstantStateDelegate = new VectorDrawableCompat.VectorDrawableDelegateState(drawable.mDelegateDrawable.getConstantState());
            return drawable;
        } else {
            try {
                XmlPullParser parser = res.getXml(resId);
                AttributeSet attrs = Xml.asAttributeSet(parser);

                int type;
                while((type = parser.next()) != 2 && type != 1) {
                    ;
                }

                if (type != 2) {
                    throw new XmlPullParserException("No start tag found");
                }

                return createFromXmlInner(res, parser, attrs, theme);
            } catch (XmlPullParserException var6) {
                Log.e("VectorDrawableCompat", "parser error", var6);
            } catch (IOException var7) {
                Log.e("VectorDrawableCompat", "parser error", var7);
            }

            return null;
        }
    }

调用影响state方法.png

根据源码,我们不难看出在24之前,通过drawable的xml解析,来上色,这样效率非常低,再通过24之后的版本,自建了一个drawable对象,在此对象中运行影响VectorView的state这样造成的后果是,VectorView的state永远赋值,当前xml下的svg永远上色为最后一个颜色。故抛弃此类写法


正确代码写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 给imageView 的svg初始化颜色
     */
    fun initSvgColor(initImgRes: InitImgRes){
        //利用ContextCompat工具类获取drawable图片资源
        val drawable = ContextCompat.getDrawable(initImgRes.context, initImgRes.imgRes)?:return
        //简单的使用tint改变drawable颜色
        val drawableResult = tintDrawable(drawable,ContextCompat.getColor(initImgRes.context, initImgRes.colorRes))
        initImgRes.imageView.setImageDrawable(drawableResult)
    }

    /**
     * 给drawable上色 
     */
     private fun  tintDrawable( drawable:Drawable, colors:Int): Drawable {
        val wrap = DrawableCompat.wrap(drawable).mutate()
        DrawableCompat.setTint(wrap,colors)
        return wrap
    }

再查看源码:

mutate方法源码解释.png

源码注释告诉了我们:此获取的drawable不与其他drawable 共享,简而言之,就是构建单独的内存模块来存储此drawable达到相互不影响的状态。

此种写法代码量减少的很明显,很能理解,先直接获取svg 的drawable 对象,然后通过预设资源,获取颜色进而给当前对象上色即可,不需要影响vectorView绘制。推荐使用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.10.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android 自定义View 之 Dialog弹窗
  在日常开发中用到弹窗是比较多的,常用于提示作用,比如错误操作提示,余额不足提示,退出登录提示等,还有用于数据展示的弹窗,上拉弹窗等等,主要为了简化在日常开发中的使用。
晨曦_LLW
2023/07/10
1.3K0
Android 自定义View 之 Dialog弹窗
Android自定义View-SVG动画
SVG是可缩放矢量图形,全称Scalable Vector Graphics。经过数学计算利用直线和曲线绘制而成,无论怎么放大,都不会出现马赛克现象。可以使用Illustrator矢量图绘图软件来进行绘图。
音视频开发进阶
2020/08/27
3K0
Android自定义View-SVG动画
Android ShapeableImageView使用详解,告别shape、三方库
由上图可以看到ShapeableImageView也没有什么神秘的,不过是ImageView的一个子类而已,但是从效果图来看,在不写shape、不引入三方库的情况下,还是挺容易实现预期效果的,而且扩展性良好。
yechaoa
2022/06/10
2.1K0
Android ShapeableImageView使用详解,告别shape、三方库
Android 自定义 Snackbar
Snackbar: Android 官方的一个控件,在 Android 应用中也算很常见了,用来显示应用交互中正在发生的消息,跟 Toast 类似,又有所区别,关于它的简单介绍和使用见上篇。Android 关于 Snackbar 基本使用。
用户8928967
2023/02/28
2K0
Android 自定义 Snackbar
Android – DataBinding 自定义setter
在APP中我们经常会遇到下面的UI 图片来源于今日头条APP个人中心界面的截图 下面咱们进入主题正式介绍如何使用databinding来自定义setter。 先上效果图: databinding自定
code_horse
2018/07/02
6250
Android的动态加载插件
我们都知道要获Res下的文件,需要用Resource对象,但是apk是未安装的,宿主并没有对应的resId,因此获取资源需要进行反编译,反编译需要对应的插件的包名,就是反编译R资源。 贴代码,举个例子: 插件管理器类
包子388321
2020/06/16
2.1K0
Android原生TabLayout使用全解析,看这篇就够了
为什么会有这篇文章呢,是因为之前关于TabLayout的使用陆陆续续也写了好几篇了,感觉比较分散,且不成体系,写这篇文章的目的就是希望能把各种效果的实现一次性讲齐,所以也有了标题的「看这篇就够了」。
yechaoa
2022/06/10
10.8K0
Android原生TabLayout使用全解析,看这篇就够了
【Android 安装包优化】Tint 着色器 ( 简介 | 布局文件中的 Tint 着色器基本用法 | 代码中使用 Tint 着色器添加颜色效果 )
Tint 着色器的作用是是 可以使图片变色 , 使用该机制可以显示不同颜色的图片 ;
韩曙亮
2023/03/29
1.9K0
【Android 安装包优化】Tint 着色器 ( 简介 | 布局文件中的 Tint 着色器基本用法 | 代码中使用 Tint 着色器添加颜色效果 )
自定义ArrayAdapter
ListView用起来还是比较简单的,也是Android应用程序中最重要的一个组件,但其他ListView可以随你所愿,能够完成很多想要的精美列表,而这正是我们接下来要学习的内容。 一、自定义ArrayAdapter 从上期自定义列表项示例知道,每个列表项的图标都一样,如果需要每个列表项的图标根据内容动态表示,Android系统的ArrayAdapter就无能为力了,就只能使用自定义ArrayAdapter来实现啦。 做法就是创建一个ArrayAdapter的子类,重写其getVie
分享达人秀
2018/02/02
1.7K0
自定义ArrayAdapter
Android – 自定义Loading圆点
网络等待Loading图 Loading.gif 刚开始做这种效果是用xml来画圆形实心点的。 白色圆点 <?xml version="1.0" encoding="utf-8"?> <s
code_horse
2018/07/02
1.3K0
Kotlin 风格,应该这样写drawable !
通常我们在res/drawable下面自定义shape和selector来满足一些UI的设计,但是由于xml最终转换为drawable需要经过IO或反射创建,会有一些性能损耗,另外随着项目的增大和模块化等,很多通用的样式并不能快速复用,需要合理的项目资源管理规范才能实施。那么通过代码直接创建这些drawable,可以在一定程度上降低这些副作用。本篇介绍用kotlin DSL简洁的语法特性来实现常见的drawable。
程序员小顾
2021/12/17
5810
Android--vector动画
上次说了SVG在安卓中的应用,在我们安卓系统中SVG就是Vector Drawable,Vector除了显示SVG图片外,还可以做动画效果,效果如下: 首先我们需要一张vector图片 在xml中为如
aruba
2020/07/03
1.4K0
Android--vector动画
Attributable_文件属性里没有自定义
在做项目的时候,用没人写的代码和看Android源码时,经常看attr.xml的使用,每次都不知道是什么意思,今天网上查了些资料,终于明白了,这里做一个笔记,方便以后使用
全栈程序员站长
2022/11/17
6370
使用Kotlin为你的APP自定义一个统一的标题栏
这篇文章只是对《为你的APP自定义一个统一的标题栏》这篇文章的Kotlin重写 ---- package com.yongxing.QianJR.widgets import android.content.Context import android.os.Build import android.support.annotation.AttrRes import android.support.annotation.DrawableRes import android.text.TextUtil
Xiaolei123
2018/06/28
1.2K0
【涨姿势】你没用过的BadgeDrawable
有的同学可能会想,能实现不就行了吗,是的,代码优不优雅、骚不骚的不重要,代码和人只要有一个能跑就行…
yechaoa
2022/06/10
1.2K0
【涨姿势】你没用过的BadgeDrawable
Android高级开发-APK极致优化
使用矢量图代替位图可以减小 APK 的尺寸,因为可以针对不同屏幕密度调整同一文件的大小,而不会降低图像质量。
Android技术干货分享
2019/06/24
1.3K0
Android高级开发-APK极致优化
相关推荐
Android 自定义View 之 Dialog弹窗
更多 >
交个朋友
加入腾讯云技术交流站
洞悉AI新动向 Get大咖技术交流群
加入HAI高性能应用服务器交流群
探索HAI应用新境界 共享实践心得
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验