Рисуемая тонировка для api <21

84

Можно ли сделать рисованную тонировку для api <21?

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary" />

Работает нормально, но только для устройств с API21. Есть ли обходной путь для устройств с более низким API или поддержки AppCompat? Ничего не могу найти.

MaTTo
источник

Ответы:

106

Используйте AppCompatImageViewтак:

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/my_appcompat_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
        android:tint="#636363"
    />

Убедитесь, что appcompat-v7в вашем приложении установлена ​​последняя версия build.gradle.

Пример: compile 'com.android.support:appcompat-v7:25.0.0'в вашем приложении build.gradle.

Сакибой
источник
66
Из AppCompatImageViewдокументов: This will automatically be used when you use ImageView in your layouts. You should only need to manually use this class when writing custom views. developer.android.com/reference/android/support/v7/widget/… Таким образом, использование обычного ImageViewмакета должно работать нормально.
Nimrod Dayan
1
Как упоминал @NimrodDayan выше, в этом нет необходимости. Однако я получаю отчеты о том, что android: tint не работает на Samsung A5 и Moto G (с использованием appcompat-v7: 23.4.0), поэтому возможно, что ImageView не заменяются должным образом на некоторых устройствах.
Стивен Кидсон
@StephenKidson, я использую ту же версию appcompat, а также столкнулся с той же проблемой на устройстве неизвестного бренда. Удалось ли вам это решить? Интересно, сообщается ли об этом об ошибке ...
Нимрод Даян
4
Это не работало на эмуляторе Android 4.0 с использованием appcompat-v7: 25.1.0.
Peterdk
4
AppCompatImageView нельзя использовать внутри виджета. Используйте setColorFilter в ImageView.
Массимо
46

Вы можете добиться этого, используя исходный код. Раньше тонировка не поддерживалась 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));
Саймон К. Гергес
источник
18
Если вам нужно поддерживать тонирование для <21 API, вы, вероятно, захотите использовать ContextCompat.getColor()вместо getResources().getColor().
Севастян Саванюк
22

Не могли бы вы просто использовать ImageView для отображения Drawable? android:tintотлично работает на более старых уровнях API.

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary"
    />
Йоник
источник
2
Я использую ImageView - для отображения в нем значка. Эти значки являются частью элементов в моем навигационном ящике. И выбранный элемент в панели навигации имеет другой цвет, поэтому я создал каждый значок с оттенком, а также селектор для каждого значка. И я использую этот селектор для своего значка. Селектор:<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@drawable/ic_home_tinted" /> <item android:drawable="@drawable/ic_home" /> </selector>
MaTTo
@Orochi Взгляните на мой ответ, поскольку он исходит непосредственно из блогов Google. В основном он работает только на Android 5.0+, но может работать и с некоторыми виджетами для устройств под управлением Android до 5.0.
Джаред Берроуз,
@Orochi Вам нужно будет создать собственные представления, чтобы «имитировать» тот же эффект.
Джаред Берроуз,
1
Вы можете использовать представление изображения, сделать значок как можно более белым и сделать его любого желаемого цвета с помощью iv.setColorFilter (yourColor, Mode.Multiply); Убедитесь, что вы импортировали android.graphics.PorterDuff.Mode
jb15613,
3
Здесь та же проблема. К сожалению, оттенок с помощью селектора не работает с api <21
Luccas
17

Подобный вопрос задавался ранее здесь: https://stackoverflow.com/a/26533340/950427

Android Drawable Tinting поддерживается только в Android 5.0+ (API 21+). (Там действительно написано " At the moment this is limited to coloring the action bar and some widgets.").

Тематика

...

Когда вы устанавливаете эти атрибуты, AppCompat автоматически передает их значения атрибутам платформы в API 21+. Это автоматически окрашивает строку состояния и запись задачи Обзор (Недавние).

На старых платформах AppCompat по возможности эмулирует цветовую тематику. На данный момент это ограничивается раскрашиванием панели действий и некоторых виджетов.

И

Тонировка виджета

При работе на устройствах с Android 5.0 все виджеты окрашиваются с использованием атрибутов цветовой темы, о которых мы только что говорили. Есть две основные функции, которые позволяют это в Lollipop: тонирование с возможностью рисования и ссылки на атрибуты темы (в форме? Attr / foo) в чертежах.

AppCompat обеспечивает аналогичное поведение в более ранних версиях Android для подмножества виджетов пользовательского интерфейса:

Все, что предусмотрено панелью инструментов AppCompat (режимы действий и т. Д.) EditText Spinner CheckBox RadioButton Switch (используйте новый android.support.v7.widget.SwitchCompat) CheckedTextView Вам не нужно делать ничего особенного, чтобы все это работало, просто используйте эти элементы управления в ваши макеты как обычно, а AppCompat сделает все остальное (с некоторыми оговорками; см. FAQ ниже).

Источники:

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

https://chris.banes.me/2014/10/17/appcompat-v21/

Джаред Берроуз
источник
Почему это было отклонено? Это из официальной документации.
Джаред Берроуз,
Ответ устарел. ImageViewтакже теперь поддерживает android:tintчерез AppCompat, как в ответе @Jonik.
Vicky Chijwani
@VickyChijwani Отправить правку. Вы имеете в виду AppCompatImageView, что нет ImageView.
Джаред Берроуз,
13

Теперь AppCompatImageView, AppCompatButton заменит ImageView, Button для поддержки оттенка на устройствах с более низким API. Проверьте ссылку для получения дополнительной информации AppCompatImageView , AppCompatButton

Анкит Сингх
источник
6

Для тонировки изображений можно использовать imageView.setColorFilter(int color). Это работает с API 8 и сработало для окрашивания моего черного изображения в желаемый цвет. Это можно заменить, setImageTintList()но простое использование android:tintтоже должно работать.

Петердк
источник
6

Используйте это NameSpace
xmlns: app = "http://schemas.android.com/apk/res-auto"

а после вы можете заменить каждый android: tint на app: tint. Это решает проблему для меня.

Сейнта
источник
4

Я немного опоздал, но вот как это сделать.

val textInput = EditText(context)

val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
drawable?.let {
    myDrawable -> DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
    textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
}
Псих
источник
1

Это будет работать так, как вы хотите, и должно работать во всех версиях библиотеки поддержки Android:

@JvmStatic
fun getTintedDrawable(inputDrawable: Drawable, @ColorInt color: Int): Drawable {
    val wrapDrawable = DrawableCompat.wrap(inputDrawable.mutate())
    DrawableCompat.setTint(wrapDrawable, color)
    DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN)
    return wrapDrawable
}
разработчик Android
источник
1

Если кто-то хочет создать новый чертеж (tin1, tint2 ..), попробуйте это

<?xml version="1.0" encoding="utf-8"?>
<bitmap
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:src="@drawable/your_image"
  android:tint="@color/tint_color">
   </bitmap>
Ранджит Кумар
источник