1、XML 设定颜色
<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代码动态设定颜色
先构造一个适用的对象
/**
* svg 图片需要构建的对象
*/
data class InitImgRes(
@DrawableRes val imgRes: Int,
@ColorRes val colorRes: Int,
val imageView: ImageView,
val context: Context
)
一般很多博客是这样写的:
/**
* 给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源码如下:
@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永远上色为最后一个颜色。故抛弃此类写法
正确代码写法:
/**
* 给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
}
再查看源码:
源码注释告诉了我们:此获取的drawable不与其他drawable 共享,简而言之,就是构建单独的内存模块来存储此drawable达到相互不影响的状态。
此种写法代码量减少的很明显,很能理解,先直接获取svg 的drawable 对象,然后通过预设资源,获取颜色进而给当前对象上色即可,不需要影响vectorView绘制。推荐使用。
网友评论