setColorFilter doesn't work on Android < 2.2

落爺英雄遲暮 提交于 2019-12-05 21:07:04

I don't know if there's another way around this, but i found that using imageView.setBackgroundDrawable() instead of imageView.setImageDrawable() resolves this issue on < 2.2.

Following on @Joe's comments and my findings for Android 2.1 from above, I think a better workaround is to apply the same colorFilter to both the Drawable as well as ImageView (unfortunatelly Drawable.getColorFilter() is only available from API 21 onwards):

d1.setColorFilter         ( 0xff00ffff, PorterDuff.Mode.MULTIPLY );
imageView.setColorFilter  ( 0xff00ffff, PorterDuff.Mode.MULTIPLY );
imageView.setImageDrawable( d1 );

One thing against for ImageView.setBackgroundDrawable() is that it won't respect ScaleType.

Probably an even better solution if you have extended ImageView already for other purposes is to fix it in the setImageDrawable() specifically for Android 2.1, where it would take the colorFilter through reflection from mBitmapState.mPaint.getColorFilter() and apply it to ImageView.

Or alternatively use ImageViewCompat class below - it requires Apache Commons Lang, you can download the JAR (and sources) from http://search.maven.org or if you use Maven or Gradle: org.apache.commons / commons-lang3. Last version to work best with Android 2.1 / Java 5 I found to be 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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!