Подтвердить что ты не робот

Android: Оттенок с использованием DrawableCompat

Я пытаюсь подкрасить изображение до уровня API Android 21. Я успешно обрабатывал элементы, используя:

<android:tint="@color/red"/>

Однако я не могу понять, как это сделать с помощью кода в ImageView:

Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);

Я попытался установить TintMode, но это, похоже, не отличается. Я неправильно использую класс совместимости v4 DrawableCompat?

4b9b3361

Ответ 1

Самый простой способ подкрасить кросс-платформу (если вам не нужен ColorStateList):

drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);

Не забывайте мутировать Drawable перед применением фильтра.

Ответ 2

В случае, если кому-то нужно использовать t t t t ting, не затрагивая другие чертежи, вот как вы это сделаете с помощью mutate():

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
wrappedDrawable = wrappedDrawable.mutate();
DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.white));

Что можно упростить до:

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));

Ответ 3

Ранее tinting не поддерживался DrawableCompat. Начиная с библиотеки поддержки 22.1 вы можете это сделать, но вам нужно сделать это следующим образом:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));

Ответ 4

Ответы здесь не работают для pre-lollipop-устройств (SupportLib 23.4.0), но я опубликовал обходное решение, которое работает для API 17 и выше: fooobar.com/questions/119969/...

Следующий код был протестирован и работает над API 17, 19, 21, 22, 23 и N Preview 3:

    // https://stackoverflow.com/a/30928051/2170109
    Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
    image.setImageDrawable(drawable);

    /*
     * need to use the filter | https://stackoverflow.com/a/30880522/2170109
     * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
     */
    int color = ContextCompat.getColor(context, R.color.yourcolor);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        DrawableCompat.setTint(drawable, color);

    } else {
        drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }

Ответ 5

Если вы посмотрите на исходный код DrawableCompat, то увидите, что для любой версии <21 метод ничего не делает.

Идея DrawableCompat, похоже, заключается не в том, чтобы рушиться на старых версиях, а в том, чтобы фактически обеспечить эту функциональность.

Ответ 6

В библиотеке поддержки 22.1 вы можете использовать DrawableCompat для рисования строк.

DrawableCompat.wrap(Drawable) и setTint(), setTintList() и setTintMode() будут работать: нет необходимости создавать и поддерживать отдельные чертежи только для поддержки нескольких цветов!

Ответ 7

Я поделюсь своим решением здесь, потому что это может сэкономить время кому-то.

У меня был ImageView с векторным drawable, используемым в качестве исходного ресурса (на самом деле это была поддержка Vector Drawable из Поддержка Android Support 23.3), Итак, сначала я обернул его так:

mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));

И после этого я попытался применить к нему так:

DrawableCompat.setTint(
    mImageView.getDrawable(),
    getResources().getColor(R.color.main_color)
);

Не повезло.

Я попробовал называть mutate() на завершаемом графическом носителе, а также на исходном чертеже - все равно не повезло. invalidate() вызванный mImageView сделал трюк.