一、改变图片颜色的应用场景
一般来讲,同一个图标,在不同的页面和不同的场景,UI设计会用不同的颜色展示。或者不同的主题,使用不同的颜色,我们当然可以每种颜色都让UI切一张图,但一方面工作繁琐无比,另一方面应用场景狭隘,不利于扩展,每次有新设计或新主题时都需要新发布一个包。最后包体积也会大大增加,因而,同一张图标,通过代码实现动态更改颜色就有了必要。
本文中,主要讲图标颜色的更改,及一张图片整体处于同一色值时的修改。当然,若图标本身某些区域带着透明度,那么透明度也会延续下来,不会被更改。所以,如果图标是一张大块区域全不透明的图片,那么就不适用以下方案,因为使用后就是一张带图片轮廓的纯色色块。
如果是针对自己绘制的shape类型drawable,也可以通过代码动态设置其色值。
如果图片为svg时,我们也可以针对不同区域(path或group)设置不同的颜色,这需要我们对svg图的xml文件进行一定的了解,无法如同png类型一般直接设置色值即可。
二、更新图标颜色的方案
2.1 通过xml直接修改图标颜色
第一种 对src设置tint 这里需要注意tint因为版本兼容的原因要使用app标签
android:src="@drawable/ic_tag"
app:tint="@color/white"
第二种 对background设置backgroundTint
android:background="@drawable/ic_tag"
android:backgroundTint="@color/blue"
第三种 针对应用最低兼容安卓版本23的应用可设置foreground及foregroundTint
android:foreground="@drawable/ic_tag"
android:src="@drawable/ic_tag"
android:foregroundTint="@color/white"
注:
- 由于foreground是前景,imageview并不会去获取其宽高设置为自身的宽高,所以在使用foreground时要么固定宽高,要么设置上src或background。并不推荐第三种方案来进行图标颜色的修改。
- 在设置tint的同时可以根据自己的需要去设置对应的tintMode,不同的mode,对图片所采用的颜色修改方式也不一样,如果只是纯粹将图标修改成另一个颜色,直接不进行设置使用默认即可
2.2 动态设置本地绘制shape类型drawable
一般来讲,本地绘制的shape都是设置到背景上,所以我们就可以进行以下设置:
val gd = view.background as? GradientDrawable
gd?.mutate() //重点注意,这里需要调用mutate()
//设置填充颜色,如果是纯色,直接设置color颜色即可,如果是渐变,则需要使用int数组设置到colors
gd?.colors = intArrayOf(bgColor,bgColor)
//设置边框,第一个参数表示宽度,后面一个表示边框的颜色,有两种取值,直接color或colorStateList
gd?.setStroke(DisplayUtil.dip2px(1f), ColorStateList.valueOf(bgColor))
注:
- 由于Android系统的缓存,使用的资源resource drawable生成后,后续使用该资源都会直接调用该对象,如果我们在代码里面动态调整了该资源的颜色而没有设置了mutate(),那么后续调用的该资源色值都是动态设置后的颜色。但如果我们设置了mutate()则表示本次修改不进行缓存。同理,我们只要是针对drawable进行颜色的动态更新,都要考虑该方法的调用
- 对填充颜色的设置,需要注意纯色设置和渐变色设置,分别是color和colors,对应的参数分别是@ColorInt int color和@ColorInt int[] colors
2.3 代码动态设置图片颜色
第一种 对imageview设置colorfilter
imageview.setColorFilter(Color.parseColor(“#de1212”))
第二种 对imageview设置imageTintList
imageview.imageTintList = ColorStateList.valueOf(colorInt)
同xml,这里也可以设置backgroundTintList = ColorStateList.valueOf(colorInt)
如果某些控件图标是button(CheckBox),可使用buttonTintList = iconsColorStates
针对textview的drawable可使用:
textView.compoundDrawables.forEach {
it?.mutate()
it?.setTintList(ColorStateList.valueOf(Color.parseColor("#02724E")).withAlpha(153)) //设置带透明度的颜色
}
注:
关于ColorStateList,如果只是单纯的某个颜色就可以直接使用ColorStateList.valueOf(colorInt),如果想针对不同的状态设置不同的颜色,则可以用ColorStateList(int[][] states, @ColorInt int[] colors)进行设置。
例如:ColorStateList(arrayOf(intArrayOf(-android.R.attr.state_checked),intArrayOf(android.R.attr.state_checked)), intArrayOf(iconRgb, iconSelectRgb))
拓展一下
ColorStateList可以设置不同状态下的颜色,那么有没有不同状态下使用不同的图标呢,当然是有的:StateListDrawable,它的使用方式类似ColorStateList,例如:
val stateListDrawable = StateListDrawable()
//按下背景 后一个参数为drawable类型
stateListDrawable.addState(intArrayOf(android.R.attr.state_pressed), pressBackGroundDrawable)
//选中背景
stateListDrawable.addState(intArrayOf(android.R.attr.state_selected), selectBackGroundDrawable)
//默认背景
stateListDrawable.addState(intArrayOf(), gradientDrawable)
view.background = stateListDrawable
上面不同状态所使用的drawable当然也可以运用上面列举的方法进行动态设置颜色。
2.4 对svg图进行动态颜色修改
有这样一张svg图,xml如下
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:name="border"
android:fillColor="#FFFFFF"
android:pathData="M512,0c255.41,0 462.45,207.05 462.45,462.45s-207.05,462.45 -462.45,462.45S49.55,717.86 49.55,462.45 256.59,0 512,0zM512,66.06C293.1,66.06 115.61,243.55 115.61,462.45s177.48,396.39 396.39,396.39 396.39,-177.48 396.39,-396.39S730.9,66.06 512,66.06z" />
<path
android:name="solid"
android:fillColor="#22C96A"
android:pathData="M512,66.06c218.9,0 396.39,177.48 396.39,396.39s-177.48,396.39 -396.39,396.39S115.61,681.36 115.61,462.45 293.1,66.06 512,66.06z" />
<path
android:name="center"
android:fillColor="#FAFFFC"
android:pathData="M444.12,534.66l237.47,-237.44a48.36,48.36 0,0 1,68.54 0.13c18.96,18.96 18.96,49.71 0.13,68.54l-268.98,268.95c-8.92,8.92 -20.38,13.64 -32.04,14.14a47.57,47.57 0,0 1,-39.21 -13.48l-136.36,-136.36a47.5,47.5 0,0 1,0.1 -67.39,47.86 47.86,0 0,1 67.39,-0.1l102.96,102.99z" />
</vector>
其中有三条路径, border为最外层的白色圆环,solid为填充绿色区域, center为最中心的白色√
这三条路径里面,除去pathData是我们不能去修改的,其他都可以由我们开发自定义。
android:name 为当前path设置名称,后续代码里面通过该名称查找该path进行颜色修改
android:fillColor 为当前path的填充颜色,后续通过代码setFillColor(int Color)进行修改
android:strokeColor 为当前path的边框颜色,后续通过代码setStrokeColor(int Color)进行修改
还有诸如strokeAlpha、strokeWidth、fillAlpha,根据名字即可知晓其作用。
代码设置其色值,例子:文章来源:https://www.toymoban.com/news/detail-742331.html
VectorChildFinder selectedVector = new VectorChildFinder(context, R.drawable.vector_drawable_ico_selected, imageView);
VectorDrawableCompat.VFullPath solid = selectedVector.findPathByName("solid");
solid.setFillColor(iconColor);
imageView.invalidate(); //重绘imageView
提出疑问:
如果一个svg图中有好些path都为相同的颜色,那么我们能不能将这些path命名为相同的名字,如果不能,那针对这种不同path动态设置相同颜色的情况,我们如何避免重复的findPathByName、setFillColor。除去findPathByName之外,还有一个findGroupByName方法,是否可以通过这个group找到办法?文章来源地址https://www.toymoban.com/news/detail-742331.html
到了这里,关于Android 改变图片颜色几种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!