根据@Joe 的 cmets 和我从上面对 Android 2.1 的发现,我认为更好的解决方法是将相同的 colorFilter 应用于 Drawable 和 ImageView(不幸的是 Drawable.getColorFilter() 仅从 API 21 开始可用):
d1.setColorFilter ( 0xff00ffff, PorterDuff.Mode.MULTIPLY );
imageView.setColorFilter ( 0xff00ffff, PorterDuff.Mode.MULTIPLY );
imageView.setImageDrawable( d1 );
ImageView.setBackgroundDrawable() 反对的一点是它不尊重 ScaleType。
如果您已经将 ImageView 扩展用于其他目的,则可能更好的解决方案是在专门针对 Android 2.1 的 setImageDrawable() 中修复它,它会通过 mBitmapState.mPaint.getColorFilter() 的反射获取 colorFilter 并应用它到图像视图。
或者使用下面的 ImageViewCompat 类 - 它需要 Apache Commons Lang,您可以从 http://search.maven.org 下载 JAR(和源代码),或者如果您使用 Maven 或 Gradle:org.apache.commons / commons-lang3。我发现最后一个最适合 Android 2.1 / Java 5 的版本是commons-lang3 v3.1
ImageViewCompat.setImageDrawable(imageView, d1);
package org.yourapp.widget;
import org.apache.commons.lang3.reflect.FieldUtils;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;
import android.widget.ImageView;
public final class ImageViewCompat {
/**
* Members
*/
private static final String TAG = ImageViewCompat.class.getSimpleName();
/**
* ImageView.setImageDrawable() backward compatible version.
*
* @param p_imageView
* @param p_drawable
*/
public static final void setImageDrawable(ImageView p_imageView, Drawable p_drawable) {
/*
* API 2.1 workaround - apply Drawable color filter to ImageView.
* @see http://stackoverflow.com/a/28108208/308836
*/
if (Build.VERSION.SDK_INT <= 7) {
if (p_drawable instanceof BitmapDrawable) {
try {
Object mBitmapState = FieldUtils.readDeclaredField(p_drawable, "mBitmapState", true);
Paint mPaint = (Paint) FieldUtils.readDeclaredField(mBitmapState, "mPaint", true);
p_imageView.setColorFilter(mPaint.getColorFilter());
}
catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
}
/*
* Set image drawable.
*/
p_imageView.setImageDrawable(p_drawable);
}
}