前几天项目上遇到了一个需求,客户需要动态配置一个活动,活动的图标是服务器配置的,app负责展示,由于设计师在展示的地方有自己的背景颜色,而图标颜色也是不一样的很可能就会产生接近或者一样的颜色,这样体验就不好了,如果能给图片动态着色那问题就迎刃而解了。一番搜索后还真有下面来总结一下。
为什么要使用DrawableCompat呢?因为从名字上看就知道他是一个Drawable的兼容包并且对低版本的手机有很好的兼容效果。
这是官方的原话:
Helper for accessing features in Drawable introduced after API level 4 in a backwards compatible fashion.
要想给图片着色需要用到下面这个及API
wrap(Drawable drawable)
setTint(Drawable drawable, int tint)
setTintList(Drawable drawable, ColorStateList tint)
-
先来看看
wrap(Drawable drawable)
方法
Potentially wrap drawable so that it may be used for tinting across the different API levels, via the tinting methods in this class.
简单的说通过这个方法获取的Drawable对象,在使用DrawableCompat类中的染色一类的方法,可以在不同的API级别上应用着色。
因此想要着色就先把原先的Drawable对象wrap一下后回去到新的Drawable对象。
后面两个方法就是染色的方法了。我们先来看看一个代码片段
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_history_sport_kll"/>
默认效果如果
使用API着色以后
ImageView iv= (ImageView) findViewById(R.id.iv);
//获取ImageView的Drawable
Drawable orig=iv.getDrawable();
//使用wrap函数获取新的Drawable
Drawable wrap=DrawableCompat.wrap(orig).mutate();
//将变换后的Drawable重新染色
DrawableCompat.setTint(wrap,ContextCompat.getColor(MainActivity.this,android.R.color.holo_red_dark));
//将染好色的Drawable设置给ImageView
iv.setImageDrawable(wrap);
-
mutate()方法
细心的同学应该发现在wrap后面多了一个函数,可以按住Ctrl键用鼠标点进去看看官方的解释;
Make this drawable mutable. This operation cannot be reversed. A mutable
drawable is guaranteed to not share its state with any other drawable.
This is especially useful when you need to modify properties of drawables
loaded from resources. By default, all drawables instances loaded from
the same resource share a common state; if you modify the state of one
instance, all the other instances will receive the same modification.
Calling this method on a mutable Drawable will have no effect.
大致的意思就是,使用这个方法,可以让一个应用中使用同样的片的地方不受影响,因为默认情况下,相同的图片资源是被共享同一种状态的。如果修改了一个实例的状态,那么其他使用这个实例的地方都会被修改。因此这个方法的作用就是让其他地方不受影响。
举个例子,比如我一个界面上有多个地方要显示同样的图片,
此时我给其中的一种图片着色且不使用mutate()反方法,你会发现另一种也跟着一起变了
这证明两个ImageView共享了同样的资源。mutae()这个时候就派上作用了。使用它就可以让另一个不受影响。
-
使用着色实现点击效果。
在点击一个控件的时候为了友好交互通常会伴有相应的点击效果。一般的做法就是改变一下原有控件的颜色。如果控件是一个纯色控件那很简单,但如果是一张图片呢?这个时候就setTintList(Drawable drawable, ColorStateList tint)
方法就派上作用了直接上代码:
Drawable orig=iv1.getDrawable();
iv1.setImageDrawable(null);
Drawable wrap=DrawableCompat.wrap(orig).mutate();
DrawableCompat.setTintList(wrap,ContextCompat.getColorStateList(this,R.color.stat));
iv1.setImageDrawable(wrap);
R.color.stat如下:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF00ff" android:state_pressed="true"/>
<item android:color="#000000" android:state_pressed="false"/>
<item android:color="#000000"/>
</selector>
这样你的图片就会有点击变色效果了。
欢迎共同探讨更多安卓,java,c/c++相关技术QQ群:392154157