前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 自定义 svg 颜色

Android 自定义 svg 颜色

作者头像
stormKid
发布2018-10-18 11:41:33
2.1K0
发布2018-10-18 11:41:33
举报
文章被收录于专栏:计算机编程

1、XML 设定颜色

代码语言:javascript
复制
  <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
复制
/**
 * svg 图片需要构建的对象
 */
data class InitImgRes(
        @DrawableRes val imgRes: Int,
        @ColorRes val colorRes: Int,
        val imageView: ImageView,
        val context: Context
)

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

代码语言:javascript
复制
   /**
     * 给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
复制
   @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
复制
    /**
     * 给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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、XML 设定颜色
  • 2、kotlin代码动态设定颜色
  • 正确代码写法:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档