setColorFilter不适用于Android< 2.2

时间:2011-04-21 22:10:11

标签: android bitmap drawable

我对drawable上的setColorFilter-Method有问题。

它在Android 2.2上运行良好,但在低于此版本的版本上运行不正常。

我的问题类似于此处所描述的问题Drawable.setColorFilter() not working on Android 2.1,但这对我不起作用......

我使用的代码在Android 2.2上运行良好,但在低于此值的任何东西上都没有。

ImageView imageView = (ImageView) findViewById( R.id.imageView1 );        
Bitmap immutableBitmap = BitmapFactory.decodeResource( getResources(), R.drawable.mybitmap );
Bitmap mutableBitmap = immutableBitmap.copy( Bitmap.Config.ARGB_8888, true );
immutableBitmap.recycle();
immutableBitmap = null;
Drawable d1 = new BitmapDrawable( mutableBitmap );
d1.setColorFilter( 0xff00ffff, PorterDuff.Mode.MULTIPLY );
imageView.setImageDrawable( d1 );

非常感谢任何使其正常工作的线索:)

2 个答案:

答案 0 :(得分:1)

我不知道是否还有另外一种解决方法,但我发现使用imageView.setBackgroundDrawable()而不是imageView.setImageDrawable()解决了这个问题< 2.2。

答案 1 :(得分:0)

关于@ Joe的评论以及我上面对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并应用它到ImageView。

或者使用下面的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);
    }
}