为啥会看到这个, 因为最近在换UI ,有一些问题就是此属性导致
icon. setTint
Tint 属性 tint 译为着色
Tint 是 Android5.0 引入的一个属性,它可以在Android5.0 系统上,对视图进行颜色渲染。 --5.0 以下support包
(1) Tint在默认只在Android5.0以上的系统生效,为了向下支持,系统提供了相应的Compact类,包括
AppCompatTextView、AppCompatImageView等。我们使用 ViewCompat.setBackgroundTintMode 在懂吗中动态的为 View 进行tint 操作,观察
这些Compat类发现都实现了 TintableBackgroundView 这个接口,如果需要让自定义的 View实现tint功能,
(2) tint这个属性,是ImageView有的,它可以给ImageView的src设置,除了tint 之外,还有
backgroundTint,
foregroundTint,
drawableTint,它们分别对应对背景、前景、drawable进行着色处理。
tintMode和backgroundTintMode有六种模式:
src_in
add
multiply
screen
src_atop
src_over
其中默认是src_in.
1. 还可以通过 tint 属性实现 选择效果 selector 效果
<ImageView
android:layout_width="150px"
android:layout_height="150px"
android:src="@drawable/selector" ---- selector 放2个一样的图即可
android:tint="@color/colortint" ---- 控制颜色
android:clickable="true"/>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@mipmap/aa"/>
<item android:drawable="@mipmap/aa"/>
</selector>
通过 tint的方式控制颜色变化
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/black"></item>
<item android:color="@color/white"></item>
</selector>
代码方式
private void setViewSelector() {
StateListDrawable stateListDrawable = new StateListDrawable();
int[][] states = new int[2][];
ImageView imageView = CreateImageView();
Drawable wrapDrawable
Drawable drawable = ContextCompat.getDrawable(this,R.mipmap.ic_launcher);
//status
states[0] = new int[]{android.R.attr.state_pressed};
states[1] = new int[]{};
//drawable
stateListDrawable.addState(states[0],drawable);
stateListDrawable.addState(states[1],drawable);
//
int[] color = new int[]{ContextCompat.getColor(this,R.color.white),ContextCompat.getColor(this,R.color.black)};
ColorStateList colorStateList = new ColorStateList(states,color);
Drawable.ConstantState state = stateListDrawable.getConstantState();
wrapDrawable = DrawableCompat.wrap(state == null ? stateListDrawable : state.newDrawable()).mutate();
//drawable
wrapDrawable.setTintList(colorStateList);
imageView.setImageDrawable(wrapDrawable);
imageView.setClickable(true);//这一步很重要,否则点击无效果
mLlContainer.addView(imageView);
}
}
原理代码,
case R.styleable.View_backgroundTint:
// This will get applied later during setBackground().
if (mBackgroundTint == null) {
mBackgroundTint = new TintInfo();
}
mBackgroundTint.mTintList = a.getColorStateList(
R.styleable.View_backgroundTint);
mBackgroundTint.mHasTintList = true;
break;
case R.styleable.View_backgroundTintMode:
// This will get applied later during setBackground().
if (mBackgroundTint == null) {
mBackgroundTint = new TintInfo();
}
mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(
R.styleable.View_backgroundTintMode, -1), null);
mBackgroundTint.mHasTintMode = true;
break;
ImageView 为例
private void applyImageTint() {
if (mDrawable != null && (mHasDrawableTint || mHasDrawableTintMode)) {
mDrawable = mDrawable.mutate();
if (mHasDrawableTint) {
mDrawable.setTintList(mDrawableTintList);
}
if (mHasDrawableTintMode) {
mDrawable.setTintMode(mDrawableTintMode);
}
// The drawable (or one of its children) may not have been
// stateful before applying the tint, so let's try again.
if (mDrawable.isStateful()) {
mDrawable.setState(getDrawableState());
}
}
setTintList 方法的实现
public void setTintList(ColorStateList tint) {
mBitmapState.mTint = tint;
// updateTintFilter(PorterDuffColorFilter,BitmapDrawable.BitmapState,PorterDuff.Mode)
mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
invalidateSelf();
}
当追踪到 updateTintFilter()它实现的方式(PorterDuffColorFilter,BitmapDrawable.BitmapState,PorterDuff.Mode),
继续进行处理
android/frameworks/base/graphics/java/android/graphics/drawable/
1409 @Nullable PorterDuffColorFilter updateTintFilter(@Nullable PorterDuffColorFilter tintFilter,
1410 @Nullable ColorStateList tint, @Nullable PorterDuff.Mode tintMode) {
1411 if (tint == null || tintMode == null) {
1412 return null;
1413 }
1414
1415 final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
1416 if (tintFilter == null) {
1417 return new PorterDuffColorFilter(color, tintMode);
1418 }
1419
1420 tintFilter.setColor(color);
1421 tintFilter.setMode(tintMode);
1422 return tintFilter;
1423 }
/
android
/
frameworks
/
base
/
graphics
/
java
/
android
/
graphics
/
PorterDuffColorFilter.java
public class PorterDuffColorFilter extends ColorFilter {
private int mColor;
private PorterDuff.Mode mMode;
public PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
mColor = color;
mMode = mode;
update();
}
............
............
public void setMode(@NonNull PorterDuff.Mode mode) {
mMode = mode;
update();
}
private void update() {
destroyFilter(native_instance);
native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
final PorterDuffColorFilter other = (PorterDuffColorFilter) object;
if (mColor != other.mColor || mMode != other.mMode) {
return false;
}
return true;
}
@Override
public int hashCode() {
return 31 * mMode.hashCode() + mColor;
}
private static native long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
}