setColorFilter在Android 2.2以下版本无法使用。

3
我在使用setColorFilter方法时遇到了问题,这与IT技术有关。该方法在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个回答

1

我不知道是否还有其他方法解决这个问题,但我发现在< 2.2上使用imageView.setBackgroundDrawable()而不是imageView.setImageDrawable()可以解决这个问题。


太好了,看起来可以工作。谢谢!你有解释为什么setImageDrawable()不起作用吗? - Marc Harding
1
我在克隆2.1源代码时遇到了问题,与2.2进行比较,但我想这可能与ImageView applyColor方法或类似方法有关...由于setBackgroundDrawable是View的超类方法并且处理方式不同,因此这个错误可能不会影响它。 - Joe
@Joe是正确的,ImageView.setImageDrawable() > updateDrawable() > applyColorMod()。在Android 2.1中,applyColorMod()总是会应用于ImageView分配的颜色过滤器(可能为空),而在后续版本中仅在特定设置时才应用它(新的mColorMod变量)。请参见http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/ImageView.java#ImageView.applyColorMod%28%29和http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/ImageView.java#ImageView.0mColorMod。 - Dan Dar3

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,那么可能更好的解决方案是在 setImageDrawable() 中专门针对 Android 2.1 进行修复,其中它将通过反射从 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 https://dev59.com/xlbTa4cB1Zd3GeqP-3Z2#28108208
         */
        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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接