Lollipop backgroundTint не влияет на кнопку

У меня есть кнопка в моей работе, и мне бы хотелось, чтобы у меня был цвет моей темы. Вместо того, чтобы создавать мои собственные чертежи, как, например, мы должны были делать 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) правильно и автоматически тонируются.

Ответ 1

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

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

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

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

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

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

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

Ответ 2

Плохая новость

Как и 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, или представления совместимости будут очень, очень грустными...;)

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

Ответ 3

Чтобы решить проблемы, связанные с tinting на 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 для всех остальных случаев.

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

Я думаю, вам нужно установить android:background, чтобы сделать работу android:backgroundTint.

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

Ответ 7

Аналогичная проблема была обнаружена в 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, как показано ниже

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

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


Android Support Library 22.1:

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

Ответ 8

Если мы рассмотрим исходный код библиотеки поддержки, мы увидим, что он обычно указывает на известные кнопки, но если мы изменим форму нашей кнопки (я имею круглую кнопку), то оттенок не работает нормально в 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);
        }

Ответ 9

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

Ответ 10

Помните, что наиболее часто обновляемая 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'

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

Ответ 11

Я не уверен, что это рекомендуется, но вы можете попробовать следующее:

Drawable newDrawable = mBtnAction.getBackground();  // obtain Bg drawable from the button as a new drawable
DrawableCompat.setTint(newDrawable, mActivity.getHomeTobBarBGColor());  //set it tint
mBtnAction.setBackground(newDrawable);  //apply back to button

В общем смысле это работает. Пробовал ViewCompat, но он не работает должным образом.