Что более эффективно - сначала установить цветовой фильтр, а затем установить растровое изображение или растровое изображение, а затем установить цветовой фильтр? - PullRequest
0 голосов
/ 15 декабря 2018

Я динамически надуваю много изображений, каждый из которых имеет свой цветовой фильтр.

Иногда приложение становится слабым, и пользовательский интерфейс начинает зависать.Я провел некоторые исследования и сейчас загружаю растровое изображение в фоновом потоке.

Тем не менее, мой вопрос заключается в том, является ли установка растрового изображения вначале для просмотра изображения, а затем настройка цветового фильтра более эффективной или сначала настройка цветового фильтра, а затем настройка растрового изображения?

1 Ответ

0 голосов
/ 15 декабря 2018

tl: dr

Настройка цветового фильтра сначала спасает вас один applyColorMode и один недействительный метод Call.Apply Color Mode ничего не делает, если у вас не установлено colorMod, и вызов onDraw в этом случае тоже не слишком дорогой, так что на самом деле это не имеет значения.

Повторный исходный код из ImageView

ЕслиСначала вы вызываете Color Filter, это происходит:

Сначала в режиме просмотра изображений вызывается setColorFilter (ColorFilter cf)

 public void setColorFilter(ColorFilter cf) {
        if (mColorFilter != cf) {
            mColorFilter = cf;
            mHasColorFilter = true;
            mColorMod = true;
            applyColorMod();
            invalidate();
        }
    }

, это применяет ColorMod, а затем делает недействительными

  private void applyColorMod() {
        // Only mutate and apply when modifications have occurred. This should
        // not reset the mColorMod flag, since these filters need to be
        // re-applied if the Drawable is changed.
        if (mDrawable != null && mColorMod) {
            mDrawable = mDrawable.mutate();
            if (mHasColorFilter) {
                mDrawable.setColorFilter(mColorFilter);
            }
            mDrawable.setXfermode(mXfermode);
            mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
        }
    }

Теперь вы устанавливаете imageBitmap

@android.view.RemotableViewMethod
public void setImageBitmap(Bitmap bm) {
    // Hacky fix to force setImageDrawable to do a full setImageDrawable
    // instead of doing an object reference comparison
    mDrawable = null;
    if (mRecycleableBitmapDrawable == null) {
        mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
    } else {
        mRecycleableBitmapDrawable.setBitmap(bm);
    }
    setImageDrawable(mRecycleableBitmapDrawable);
}

, это вызывает setImageDrawable

public void setImageDrawable(@Nullable Drawable drawable) {
    if (mDrawable != drawable) {
        mResource = 0;
        mUri = null;
        final int oldWidth = mDrawableWidth;
        final int oldHeight = mDrawableHeight;
        updateDrawable(drawable);
        if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
            requestLayout();
        }
        invalidate();
    }
}

, вызывая updateDrawable до аннулирования:

  @UnsupportedAppUsage
    private void updateDrawable(Drawable d) {
        if (d != mRecycleableBitmapDrawable && mRecycleableBitmapDrawable != null) {
            mRecycleableBitmapDrawable.setBitmap(null);
        }
        boolean sameDrawable = false;
        if (mDrawable != null) {
            sameDrawable = mDrawable == d;
            mDrawable.setCallback(null);
            unscheduleDrawable(mDrawable);
            if (!sCompatDrawableVisibilityDispatch && !sameDrawable && isAttachedToWindow()) {
                mDrawable.setVisible(false, false);
            }
        }
        mDrawable = d;
        if (d != null) {
            d.setCallback(this);
            d.setLayoutDirection(getLayoutDirection());
            if (d.isStateful()) {
                d.setState(getDrawableState());
            }
            if (!sameDrawable || sCompatDrawableVisibilityDispatch) {
                final boolean visible = sCompatDrawableVisibilityDispatch
                        ? getVisibility() == VISIBLE
                        : isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown();
                d.setVisible(visible, true);
            }
            d.setLevel(mLevel);
            mDrawableWidth = d.getIntrinsicWidth();
            mDrawableHeight = d.getIntrinsicHeight();
            applyImageTint();
            applyColorMod();
            configureBounds();
        } else {
            mDrawableWidth = mDrawableHeight = -1;
        }
    }
...