Фоновый оттенок Lollipop не влияет на кнопку

У меня есть кнопка в моей работе, и мне бы хотелось, чтобы у меня был цвет акцента моей темы. Вместо того, чтобы делать мои собственные чертежи, как мы должны были делать pre-Lollipop, естественно, я бы хотел использовать новый атрибут backgroundTint .

 <Button android:id="@+id/btnAddCode" android:layout_width="match_parent" android:layout_height="wrap_content" android:backgroundTint="@color/accent" android:text="@string/addressInfo_edit_addCode" /> 

К сожалению, это не действует, кнопка остается серой.

Я пробовал разные значения для backgroundTintMode , который ничего не менял.

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

 addCodeView.findViewById(R.id.btnAddCode).setBackgroundTintList( getResources().getColorStateList(R.color.accent)); 

Почему мой оттенок игнорируется?

EDIT: Чтобы уточнить, я действительно тестирую устройство Lollipop. Другие виджеты (например, EditText) корректно и автоматически тонируются.

Плохие новости

Как и BoD, бессмысленно оттенять фон Button в Lollipop 5.0 (уровень API 21).

Хорошие новости

Lollipop 5.1 (API-уровень 22), похоже, исправил это, изменив btn_mtrl_default_shape.xml (среди других файлов): https://android.googlesource.com/platform/frameworks/base/+/6dfa60f33ca6018959ebff1efde82db7d2aed1e3%5E!/#F0

Отличные новости

Новая библиотека поддержки (версия 22.1+) добавляет обратно-совместимую поддержку тонирования множеству компонентов, включая AppCompatButton !

К сожалению, свойство android:backgroundTint прежнему не работает (возможно, я делаю что-то неправильно) – поэтому вам нужно установить ColorStateList в коде, используя setSupportBackgroundTintList() . Было бы неплохо увидеть android:backgroundTint поддерживается в будущем. Обновление : Марсио Гранзотто отметил, что app:backgroundTint работает на AppCompatButton! Обратите внимание, что это app: не android: потому что оно находится в приложении / библиотеке.

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <AppCompatButton android:id="@+id/mybutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Testing, testing" app:backgroundTint="#ff00ff"/> </LinearLayout> 

Ваша активность автоматически раздувает AppCompatButton вместо обычной Button если вы позволите ей наследовать от AppCompatActivity .

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AppCompatButton v = (AppCompatButton) findViewById(R.id.mybutton); ColorStateList csl = new ColorStateList(new int[][]{new int[0]}, new int[]{0xffffcc00}); v.setSupportBackgroundTintList(csl); } } 

Конечно, вы должны получить ColorStateList из цветового ресурса, но я был ленив, поэтому …

О, и не забудьте основать тему приложения на одной из тем Theme.AppCompat , или взгляды Theme.AppCompat будут очень, очень грустными …;)

Это работало как на 2.3.7 (Gingerbread MR1), так и на 5.0 (Lollipop 'Classic').

Кажется, что тонирование тиража не имеет смысла (и фон по умолчанию кнопки – это рябь).

На самом деле, посмотрев на кнопку по умолчанию для платформы, можно найти «правильный» способ сделать это :. Вы должны определить это в своей теме:

  <item name="android:colorButtonNormal">@color/accent</item> 

(Конечно, это только для уровня 21+.)

Предупреждение: поскольку это определено в теме, это будет использовать заданный цвет для всех кнопок (по крайней мере, все кнопки в действиях с использованием этой темы.)

В качестве бонуса вы также можете изменить цвет пульсации, указав это:

  <item name="android:colorControlHighlight">@color/accent_ripple</item> 

Чтобы решить проблемы, связанные с тонированием на Android 5.0.x, я использую что-то вроде этого:

 public static void setButtonTint(Button button, ColorStateList tint) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP && button instanceof AppCompatButton) { ((AppCompatButton) button).setSupportBackgroundTintList(tint); } else { ViewCompat.setBackgroundTintList(button, tint); } } 

Он использует метод поддержки только для API 21 и ViewCompat для всех остальных случаев.

Просто используйте app:backgroundTint вместо android:backgroundTint , оттенок будет действовать ниже Lollipop. Причина заключается в том, что AppCompatActivity использует AppCompatViewInflater для автоматической смены Button или TextView на AppCompatButton или AppCompatTextView, а затем app:backgroundTint вступит в силу.

Введите описание изображения здесь

В моем проекте я использовал его, он работал.

Я обычно делаю это динамически, используя PorterDuff:

 mbutton = (Button) findViewById(R.id.mybutton); mbutton.getBackground().setColorFilter(anycolor, PorterDuff.Mode.MULTIPLY); 

Здесь вы можете проверить различные режимы смешивания и примеры.

Я думаю, вам нужно иметь android:background установленный для создания android:backgroundTint .

Чтобы быть более точным, я предполагаю, что вы не можете использовать backgroundTint кнопки по умолчанию из Материалов, который определяется как RippleDrawable .

Аналогичная проблема возникла по адресу google https://code.google.com/p/android/issues/detail?id=201873.

Но после выхода Android Support Library, редакция 23.2.1 (март 2016 г.) Эта ошибка решена.

Проблема: FloatingActionButton.setBackgroundTintList (оттенок @Nullable ColorStateList) больше не изменяет цвет фона

Обновить библиотеку Android Support Library to 23.2.1

Используйте библиотеку поддержки дизайна (23.2.1) и appcompatwidgets, как показано ниже.

Конструкция материала для устройств с предварительным охлаждением :

AppCompat (aka ActionBarCompat) начал работать как backport для Android 4.0 ActionBar API для устройств, работающих на Gingerbread, обеспечивая общий уровень API поверх реализации с поддержкой backported и реализации фреймворка. AppCompat v21 предоставляет API и набор функций, обновляемый с Android 5.0


Библиотека поддержки Android 22.1 :

Возможность автоматически настраивать виджеты при использовании AppCompat невероятно полезна в сохранении сильного брендинга и согласованности во всем приложении. Это делается автоматически при раздувании макетов – замена кнопки с помощью AppCompatButton, TextView с AppCompatTextView и т. Д., Чтобы гарантировать, что каждый из них может поддерживать тонирование. В этом выпуске эти видимые виджеты теперь общедоступны, что позволяет поддерживать поддержку тонирования, даже если вам нужно подклассифицировать один из поддерживаемых виджетов.

Если мы посмотрим на исходный код библиотеки поддержки, мы увидим, что он обычно указывает на привычные кнопки, но если мы изменим форму нашей кнопки (я имею круглую кнопку), то оттенок не работает нормально в api <= 21. Мы также можем видеть, что TintManager стал общедоступным классом (appcompat-v7: 23.1.1), поэтому мы можем взять ColorStateList из формы кнопки по умолчанию (то есть ok в 5.0) для текущей темы (так что нам не нужно создавать массив Цветов):

  Context c = ...; // activity AppCompatButton ab = ...; // your button // works ok in 22+: if (Build.VERSION.SDK_INT <= 21) { // default appcompat button, that is tinted ok with current theme colors "abc_btn_default_mtrl_shape": // ColorStateList tint = TintManager.get(c).getTintList(R.drawable.abc_btn_default_mtrl_shape); // Appcompat 23.2 change: ColorStateList tint = AppCompatDrawableManager.get().getTintList(c, R.drawable.abc_btn_default_mtrl_shape); ab.setSupportBackgroundTintList(tint); } 

Поскольку атрибут backgroundTint используется только в API уровня 21 и выше

Помните, что наиболее часто обновляемая lib может вызвать эту ошибку.

Эта команда

  sendBtnView.setBackgroundTintList(colorState) 

Отлично работала в прошлом, но перестала работать на меня. После исследования выясняется, что причиной является lib, который был добавлен к зависимостям gradle:

  compile 'com.android.support:recyclerview-v7:+' 

Поэтому я попытался изменить его на 23.02.1, как это было рекомендовано здесь в сообщении Amit Vaghela. Я перешел на

  compile 'com.android.support:recyclerview-v7:23.02.1' 

Но ошибка gradle говорит, что recyclerview lib не имеет этой версии (23.02.1) (gradle не смог найти ее в Jcenter raw.github или repo).

Тогда, becaouse, я знал, что команда setBackgroundTintList используется, чтобы хорошо работать в прошлом с версией 22.02.0 'во всех других библиотеках, которые у меня есть в зависимостях gradle. Поэтому я меняю его на:

 compile 'com.android.support:recyclerview-v7:22.02.0' 

И теперь это работает снова.