Программный оттенок вектора поддержки

Android Studio версии 2.1, gradle версия 2.1.0, пожалуйста, исправьте меня, если вы заметите какие-либо неверные толкования:)

Я смущен о вспомогательных векторах в библиотеке поддержки 23.3.0. В частности, то, что я хотел бы сделать, - это тонировка кнопки изображения программно, чей src определен, является векторным. Из того, что я могу сказать, сейчас это невозможно на pre-lollipop.

Я прочитал несколько связанных сообщений об изменениях: 23.2.0 объявление и изменения:

Как и в Android Support Library 23.3.0, поддержка векторных чертежей может быть загружена только через приложение: srcCompat или setImageResource().

Означает ли это, что вектор xmls можно использовать только pre-Lollipop через srcCompat или setImageResource(), и поэтому не может быть динамически тонирован?

Вот моя основная кнопка изображения:

<ImageButton
    android:id="@+id/nav_header_exit_community_button"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:background="@null"/>

Работает только на Lollipop и выше:

    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);

Попытка этого прелолопольного броска: android.content.res.Resources$NotFoundException: File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID #0x7f0200bf

Также работает только на Lollipop и выше

    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageResource(R.drawable.ic_exit_to_app_24dp);

Это порождает ту же ошибку при пред-Lollipop.

Однако, если я удаляю vectorDrawables.useSupportLibrary = true, как указано здесь здесь Ian Lake, с целью создания автоматических генераторов для создания предпродажных устройств Lollipop, png не накладываются на pre-lollipop, поэтому я возвращаюсь к квадрату.

Я также попытался указать вектор через srcCompat и получить его программным способом, но я не думаю, что смог достичь этого, даже если он работает на post-Lollipop, если вектор указан с помощью src вместо этого.

Итак, ситуация для 23.3.0 выглядит следующим образом:

  • Post-Lollipop: src и srcCompat принимают векторы, только src может быть извлекается из представления как готовое для тонирования программно. Ссылка на векторы в коде возможна с помощью getDrawable, и они может быть окрашен.

  • Pre-Lollipop: srcCompat может принимать только векторы, не может быть восстановлен программно из представления для тонирования. setImageResource может принимают векторы, но только если vectorDrawables.useSupportLibrary = false, а тонирование не работает. Аналогичным образом ссылки на векторы в коде не возможно, если vectorDrawables.useSupportLibrary = false и тонирование не работает.

Работа со всеми версиями с помощью png:

   Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_nav_exit_community);
   DrawableCompat.setTint(bg, headerTitleColor);
   exitButton.setImageDrawable(bg);

Приложение:

Эта техника также работает на пост-Lollipop, но, как и другие на pre-Lollipop, я получаю возможность рисования, но без тонирования:

    Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);

ВИД РЕШЕНИЯ:

Благодаря John до сих пор единственным надежным способом, который я могу придумать, чтобы подчеркнуть вектор поддержки, является установка на него цветового фильтра - это означает функция DrawableCompat.setTint(), по-видимому, не работает для меня, если рассматриваемый вопрос является вспомогательным вектором. Я не уверен, что это законная ошибка, ожидаемое поведение или если я просто делаю что-то неправильно!

Вот решение, на котором я собираюсь на данный момент:

    Drawable bg;
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
        exitButton.setColorFilter(headerTitleColor, PorterDuff.Mode.MULTIPLY);
    }
    else {
        bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
        DrawableCompat.setTint(bg, headerTitleColor);
    }
    exitButton.setImageDrawable(bg);

Ответ 1

в первую очередь вы должны использовать VectorDrawableCompat#create, как только у вас есть Drawable, вам нужно позвонить DrawableCompat#wrap:

Потенциально обернуть ленту, чтобы ее можно было использовать для тонирования различные уровни API, используя методы тонирования в этом классе.

поэтому ваш код будет выглядеть так:

ImageView iv = ....
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null);
d = DrawableCompat.wrap(d);
DrawableCompat.setTint(d, headerTitleColor);
iv.setImageDrawable(d);

Ответ 2

Вы можете использовать setColorFilter метод ImageView:

imageView.setColorFilter(headerTitleColor, android.graphics.PorterDuff.Mode.MULTIPLY);