setColorFilter не работает на Android <2.2 - PullRequest
3 голосов
/ 22 апреля 2011

У меня проблема с методом setColorFilter для рисования.

Отлично работает на Android 2.2, но не на версии ниже этой.

Моя проблема похожа на описанную здесь Drawable.setColorFilter () не работает на 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 голос
/ 22 апреля 2011

Я не знаю, есть ли другой способ обойти это, но я обнаружил, что использование imageView.setBackgroundDrawable() вместо imageView.setImageDrawable() решает эту проблему на <2.2. </p>

0 голосов
/ 23 января 2015

Исходя из комментариев @ Джо и моих выводов для 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, где он берет colorFilter через отражение от mBitmapState.mPaint.getColorFilter () и применяет его в ImageView.

Или альтернативно используйте приведенный ниже класс ImageViewCompat - для него требуется Apache Commons Lang , вы можете загрузить JAR (и исходные коды) из http://search.maven.org или если вы используете 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);
    }
}
...