在 ImageFilterView 中以编程方式设置 android:altSrc?
Set android:altSrc programmatically in ImageFilterView?
这是我的布局元素。
<android.support.constraint.utils.ImageFilterView
android:id="@+id/start_track"
android:layout_width="96dp" android:layout_height="49dp"
android:src="@drawable/icons_copy_6"
app:altSrc="@drawable/icons_copy_4"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:visibility="visible"/>
并且在 Activity 中,我正在如下初始化此视图。
ImageFilterView thumb = v.findViewById(R.id.start_thumb);
我可以将图片 src 设置如下
thumb.setImageDrawable(getResources().getDrawable(mThumbDisabled));
如何动态设置app:altSrc="@drawable/icons_copy_4"
?
您可以创建一个扩展 AppCompatImageView 的自定义视图
public class CustomImageFilterView extends AppCompatImageView {
float[] m = new float[20];
ColorMatrix mColorMatrix = new ColorMatrix();
ColorMatrix mTmpColorMatrix = new ColorMatrix();
private float mSaturation = 1.0F;
private float mContrast = 1.0F;
private float mWarmth = 1.0F;
private float mCrossfade = 0.0F;
private AttributeSet attributeSet;
Drawable[] mLayers;
LayerDrawable mLayer;
public CustomImageFilterView(Context context) {
super(context);
this.init(context, (AttributeSet)null);
}
public CustomImageFilterView(Context context, AttributeSet attrs) {
super(context, attrs);
this.init(context, attrs);
}
public CustomImageFilterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
this.attributeSet = attrs;
if (attrs != null) {
TypedArray a = this.getContext().obtainStyledAttributes(attrs, R.styleable.CustomImageFilterView);
int N = a.getIndexCount();
Drawable drawable = a.getDrawable(R.styleable.CustomImageFilterView_customDrawable);
for(int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
if (attr == android.support.constraint.R.styleable.ImageFilterView_crossfade) {
this.mCrossfade = a.getFloat(attr, 0.0F);
}
}
a.recycle();
if (drawable != null) {
this.mLayers = new Drawable[2];
this.mLayers[0] = this.getDrawable();
this.mLayers[1] = drawable;
this.mLayer = new LayerDrawable(this.mLayers);
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
}
public void setAltDrawable(Drawable drawable) {
TypedArray a = this.getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomImageFilterView);
int N = a.getIndexCount();
for(int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
if (attr == android.support.constraint.R.styleable.ImageFilterView_crossfade) {
this.mCrossfade = a.getFloat(attr, 0.0F);
}
}
a.recycle();
if (drawable != null) {
this.mLayers = new Drawable[2];
this.mLayers[0] = this.getDrawable();
this.mLayers[1] = drawable;
this.mLayer = new LayerDrawable(this.mLayers);
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
public void setSaturation(float saturation) {
this.mSaturation = saturation;
this.updateMatrix();
}
public float getSaturation() {
return this.mSaturation;
}
public void setContrast(float contrast) {
this.mContrast = contrast;
this.updateMatrix();
}
public float getContrast() {
return this.mContrast;
}
public void setWarmth(float warmth) {
this.mWarmth = warmth;
this.updateMatrix();
}
public float getWarmth() {
return this.mWarmth;
}
public void setCrossfade(float crossfade) {
this.mCrossfade = crossfade;
if (this.mLayers != null) {
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
public float getCrossfade() {
return this.mCrossfade;
}
private void saturation(float saturationStrength) {
float Rf = 0.2999F;
float Gf = 0.587F;
float Bf = 0.114F;
float MS = 1.0F - saturationStrength;
float Rt = Rf * MS;
float Gt = Gf * MS;
float Bt = Bf * MS;
this.m[0] = Rt + saturationStrength;
this.m[1] = Gt;
this.m[2] = Bt;
this.m[3] = 0.0F;
this.m[4] = 0.0F;
this.m[5] = Rt;
this.m[6] = Gt + saturationStrength;
this.m[7] = Bt;
this.m[8] = 0.0F;
this.m[9] = 0.0F;
this.m[10] = Rt;
this.m[11] = Gt;
this.m[12] = Bt + saturationStrength;
this.m[13] = 0.0F;
this.m[14] = 0.0F;
this.m[15] = 0.0F;
this.m[16] = 0.0F;
this.m[17] = 0.0F;
this.m[18] = 1.0F;
this.m[19] = 0.0F;
}
private void warmth(float warmth) {
float baseTemprature = 5000.0F;
if (warmth <= 0.0F) {
warmth = 0.01F;
}
float kelvin = baseTemprature / warmth;
float color_r = kelvin / 100.0F;
float color_g;
float color_b;
float colorR;
if (color_r > 66.0F) {
colorR = color_r - 60.0F;
color_g = 329.69873F * (float)Math.pow((double)colorR, -0.13320475816726685D);
color_b = 288.12216F * (float)Math.pow((double)colorR, 0.07551484555006027D);
} else {
color_b = 99.4708F * (float)Math.log((double)color_r) - 161.11957F;
color_g = 255.0F;
}
float centiKelvin;
if (color_r < 66.0F) {
if (color_r > 19.0F) {
centiKelvin = 138.51773F * (float)Math.log((double)(color_r - 10.0F)) - 305.0448F;
} else {
centiKelvin = 0.0F;
}
} else {
centiKelvin = 255.0F;
}
float tmpColor_r = Math.min(255.0F, Math.max(color_g, 0.0F));
float tmpColor_g = Math.min(255.0F, Math.max(color_b, 0.0F));
float tmpColor_b = Math.min(255.0F, Math.max(centiKelvin, 0.0F));
color_r = tmpColor_r;
color_g = tmpColor_g;
color_b = tmpColor_b;
centiKelvin = baseTemprature / 100.0F;
float colorG;
if (centiKelvin > 66.0F) {
float tmp = centiKelvin - 60.0F;
colorR = 329.69873F * (float)Math.pow((double)tmp, -0.13320475816726685D);
colorG = 288.12216F * (float)Math.pow((double)tmp, 0.07551484555006027D);
} else {
colorG = 99.4708F * (float)Math.log((double)centiKelvin) - 161.11957F;
colorR = 255.0F;
}
float colorB;
if (centiKelvin < 66.0F) {
if (centiKelvin > 19.0F) {
colorB = 138.51773F * (float)Math.log((double)(centiKelvin - 10.0F)) - 305.0448F;
} else {
colorB = 0.0F;
}
} else {
colorB = 255.0F;
}
tmpColor_r = Math.min(255.0F, Math.max(colorR, 0.0F));
tmpColor_g = Math.min(255.0F, Math.max(colorG, 0.0F));
tmpColor_b = Math.min(255.0F, Math.max(colorB, 0.0F));
color_r /= tmpColor_r;
color_g /= tmpColor_g;
color_b /= tmpColor_b;
this.m[0] = color_r;
this.m[1] = 0.0F;
this.m[2] = 0.0F;
this.m[3] = 0.0F;
this.m[4] = 0.0F;
this.m[5] = 0.0F;
this.m[6] = color_g;
this.m[7] = 0.0F;
this.m[8] = 0.0F;
this.m[9] = 0.0F;
this.m[10] = 0.0F;
this.m[11] = 0.0F;
this.m[12] = color_b;
this.m[13] = 0.0F;
this.m[14] = 0.0F;
this.m[15] = 0.0F;
this.m[16] = 0.0F;
this.m[17] = 0.0F;
this.m[18] = 1.0F;
this.m[19] = 0.0F;
}
private void updateMatrix() {
this.mColorMatrix.reset();
boolean filter = false;
if (this.mSaturation != 1.0F) {
this.saturation(this.mSaturation);
this.mColorMatrix.set(this.m);
filter = true;
}
if (this.mContrast != 1.0F) {
this.mTmpColorMatrix.setScale(this.mContrast, this.mContrast, this.mContrast, 1.0F);
this.mColorMatrix.postConcat(this.mTmpColorMatrix);
filter = true;
}
if (this.mWarmth != 1.0F) {
this.warmth(this.mWarmth);
this.mTmpColorMatrix.set(this.m);
this.mColorMatrix.postConcat(this.mTmpColorMatrix);
filter = true;
}
if (filter) {
this.setColorFilter(new ColorMatrixColorFilter(this.mColorMatrix));
} else {
this.clearColorFilter();
}
}
并创建自定义样式
<resources>
<declare-styleable name="CustomImageFilterView">
<attr name="customDrawable" format="reference" />
</declare-styleable>
自定义视图 class 有一个 setter 方法可以动态设置 alt drawable
setAltDrawable 传递可绘制对象,瞧。
这是我的布局元素。
<android.support.constraint.utils.ImageFilterView
android:id="@+id/start_track"
android:layout_width="96dp" android:layout_height="49dp"
android:src="@drawable/icons_copy_6"
app:altSrc="@drawable/icons_copy_4"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:visibility="visible"/>
并且在 Activity 中,我正在如下初始化此视图。
ImageFilterView thumb = v.findViewById(R.id.start_thumb);
我可以将图片 src 设置如下
thumb.setImageDrawable(getResources().getDrawable(mThumbDisabled));
如何动态设置app:altSrc="@drawable/icons_copy_4"
?
您可以创建一个扩展 AppCompatImageView 的自定义视图
public class CustomImageFilterView extends AppCompatImageView {
float[] m = new float[20];
ColorMatrix mColorMatrix = new ColorMatrix();
ColorMatrix mTmpColorMatrix = new ColorMatrix();
private float mSaturation = 1.0F;
private float mContrast = 1.0F;
private float mWarmth = 1.0F;
private float mCrossfade = 0.0F;
private AttributeSet attributeSet;
Drawable[] mLayers;
LayerDrawable mLayer;
public CustomImageFilterView(Context context) {
super(context);
this.init(context, (AttributeSet)null);
}
public CustomImageFilterView(Context context, AttributeSet attrs) {
super(context, attrs);
this.init(context, attrs);
}
public CustomImageFilterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
this.attributeSet = attrs;
if (attrs != null) {
TypedArray a = this.getContext().obtainStyledAttributes(attrs, R.styleable.CustomImageFilterView);
int N = a.getIndexCount();
Drawable drawable = a.getDrawable(R.styleable.CustomImageFilterView_customDrawable);
for(int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
if (attr == android.support.constraint.R.styleable.ImageFilterView_crossfade) {
this.mCrossfade = a.getFloat(attr, 0.0F);
}
}
a.recycle();
if (drawable != null) {
this.mLayers = new Drawable[2];
this.mLayers[0] = this.getDrawable();
this.mLayers[1] = drawable;
this.mLayer = new LayerDrawable(this.mLayers);
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
}
public void setAltDrawable(Drawable drawable) {
TypedArray a = this.getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomImageFilterView);
int N = a.getIndexCount();
for(int i = 0; i < N; ++i) {
int attr = a.getIndex(i);
if (attr == android.support.constraint.R.styleable.ImageFilterView_crossfade) {
this.mCrossfade = a.getFloat(attr, 0.0F);
}
}
a.recycle();
if (drawable != null) {
this.mLayers = new Drawable[2];
this.mLayers[0] = this.getDrawable();
this.mLayers[1] = drawable;
this.mLayer = new LayerDrawable(this.mLayers);
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
public void setSaturation(float saturation) {
this.mSaturation = saturation;
this.updateMatrix();
}
public float getSaturation() {
return this.mSaturation;
}
public void setContrast(float contrast) {
this.mContrast = contrast;
this.updateMatrix();
}
public float getContrast() {
return this.mContrast;
}
public void setWarmth(float warmth) {
this.mWarmth = warmth;
this.updateMatrix();
}
public float getWarmth() {
return this.mWarmth;
}
public void setCrossfade(float crossfade) {
this.mCrossfade = crossfade;
if (this.mLayers != null) {
this.mLayer.getDrawable(1).setAlpha((int)(255.0F * this.mCrossfade));
super.setImageDrawable(this.mLayer);
}
}
public float getCrossfade() {
return this.mCrossfade;
}
private void saturation(float saturationStrength) {
float Rf = 0.2999F;
float Gf = 0.587F;
float Bf = 0.114F;
float MS = 1.0F - saturationStrength;
float Rt = Rf * MS;
float Gt = Gf * MS;
float Bt = Bf * MS;
this.m[0] = Rt + saturationStrength;
this.m[1] = Gt;
this.m[2] = Bt;
this.m[3] = 0.0F;
this.m[4] = 0.0F;
this.m[5] = Rt;
this.m[6] = Gt + saturationStrength;
this.m[7] = Bt;
this.m[8] = 0.0F;
this.m[9] = 0.0F;
this.m[10] = Rt;
this.m[11] = Gt;
this.m[12] = Bt + saturationStrength;
this.m[13] = 0.0F;
this.m[14] = 0.0F;
this.m[15] = 0.0F;
this.m[16] = 0.0F;
this.m[17] = 0.0F;
this.m[18] = 1.0F;
this.m[19] = 0.0F;
}
private void warmth(float warmth) {
float baseTemprature = 5000.0F;
if (warmth <= 0.0F) {
warmth = 0.01F;
}
float kelvin = baseTemprature / warmth;
float color_r = kelvin / 100.0F;
float color_g;
float color_b;
float colorR;
if (color_r > 66.0F) {
colorR = color_r - 60.0F;
color_g = 329.69873F * (float)Math.pow((double)colorR, -0.13320475816726685D);
color_b = 288.12216F * (float)Math.pow((double)colorR, 0.07551484555006027D);
} else {
color_b = 99.4708F * (float)Math.log((double)color_r) - 161.11957F;
color_g = 255.0F;
}
float centiKelvin;
if (color_r < 66.0F) {
if (color_r > 19.0F) {
centiKelvin = 138.51773F * (float)Math.log((double)(color_r - 10.0F)) - 305.0448F;
} else {
centiKelvin = 0.0F;
}
} else {
centiKelvin = 255.0F;
}
float tmpColor_r = Math.min(255.0F, Math.max(color_g, 0.0F));
float tmpColor_g = Math.min(255.0F, Math.max(color_b, 0.0F));
float tmpColor_b = Math.min(255.0F, Math.max(centiKelvin, 0.0F));
color_r = tmpColor_r;
color_g = tmpColor_g;
color_b = tmpColor_b;
centiKelvin = baseTemprature / 100.0F;
float colorG;
if (centiKelvin > 66.0F) {
float tmp = centiKelvin - 60.0F;
colorR = 329.69873F * (float)Math.pow((double)tmp, -0.13320475816726685D);
colorG = 288.12216F * (float)Math.pow((double)tmp, 0.07551484555006027D);
} else {
colorG = 99.4708F * (float)Math.log((double)centiKelvin) - 161.11957F;
colorR = 255.0F;
}
float colorB;
if (centiKelvin < 66.0F) {
if (centiKelvin > 19.0F) {
colorB = 138.51773F * (float)Math.log((double)(centiKelvin - 10.0F)) - 305.0448F;
} else {
colorB = 0.0F;
}
} else {
colorB = 255.0F;
}
tmpColor_r = Math.min(255.0F, Math.max(colorR, 0.0F));
tmpColor_g = Math.min(255.0F, Math.max(colorG, 0.0F));
tmpColor_b = Math.min(255.0F, Math.max(colorB, 0.0F));
color_r /= tmpColor_r;
color_g /= tmpColor_g;
color_b /= tmpColor_b;
this.m[0] = color_r;
this.m[1] = 0.0F;
this.m[2] = 0.0F;
this.m[3] = 0.0F;
this.m[4] = 0.0F;
this.m[5] = 0.0F;
this.m[6] = color_g;
this.m[7] = 0.0F;
this.m[8] = 0.0F;
this.m[9] = 0.0F;
this.m[10] = 0.0F;
this.m[11] = 0.0F;
this.m[12] = color_b;
this.m[13] = 0.0F;
this.m[14] = 0.0F;
this.m[15] = 0.0F;
this.m[16] = 0.0F;
this.m[17] = 0.0F;
this.m[18] = 1.0F;
this.m[19] = 0.0F;
}
private void updateMatrix() {
this.mColorMatrix.reset();
boolean filter = false;
if (this.mSaturation != 1.0F) {
this.saturation(this.mSaturation);
this.mColorMatrix.set(this.m);
filter = true;
}
if (this.mContrast != 1.0F) {
this.mTmpColorMatrix.setScale(this.mContrast, this.mContrast, this.mContrast, 1.0F);
this.mColorMatrix.postConcat(this.mTmpColorMatrix);
filter = true;
}
if (this.mWarmth != 1.0F) {
this.warmth(this.mWarmth);
this.mTmpColorMatrix.set(this.m);
this.mColorMatrix.postConcat(this.mTmpColorMatrix);
filter = true;
}
if (filter) {
this.setColorFilter(new ColorMatrixColorFilter(this.mColorMatrix));
} else {
this.clearColorFilter();
}
}
并创建自定义样式
<resources>
<declare-styleable name="CustomImageFilterView">
<attr name="customDrawable" format="reference" />
</declare-styleable>
自定义视图 class 有一个 setter 方法可以动态设置 alt drawable setAltDrawable 传递可绘制对象,瞧。