Как поменять цвет кнопки в Android Studio: меняем фон и текст

Стандартная фиолетовая кнопка, которую Android Studio создаёт по умолчанию, редко вписывается в дизайн реального приложения. Разработчику постоянно нужно менять цвет фона, текста или подсветки при нажатии. В этом руководстве я собрал все рабочие способы того, как поменять цвет кнопки в android studio: от простого атрибута в XML до программной смены цвета в Kotlin-коде и настройки глобальных стилей.


Почему кнопка может не менять цвет

Прежде чем переходить к решению, нужно понять корень проблемы. Начиная с Android Studio 4.1, все новые проекты по умолчанию используют тему Theme.MaterialComponents. Это означает, что обычный <Button> в разметке автоматически превращается в MaterialButton — компонент из библиотеки Material Design.

У MaterialButton есть особенность: он игнорирует атрибут android:background. Вместо этого для управления цветом фона используется app:backgroundTint. Если вы попытаетесь задать android:background="#FF0000", ничего не произойдёт — кнопка останется фиолетовой. Именно эта особенность вызывает больше всего вопросов у новичков.


Способ 1: Меняем цвет через XML-атрибуты

Самый простой и правильный путь для MaterialButton — использовать атрибут app:backgroundTint. Он меняет цвет фона, сохраняя скругления, тени и анимацию нажатия.

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Нажми меня"
    app:backgroundTint="#4CAF50"
    android:textColor="#FFFFFF" />

Обратите внимание: нужно объявить пространство имён xmlns:app="http://schemas.android.com/apk/res-auto" в корневом элементе разметки. Без него атрибуты с префиксом app: не будут работать. Цвет фона задан зелёным, а текст — белым.

Этот способ подходит для большинства ситуаций. Он лаконичен, работает в предпросмотре Android Studio и не требует написания дополнительных файлов.


Способ 2: Программное изменение цвета в Kotlin

Иногда цвет кнопки нужно поменять динамически — например, после ответа от сервера или по таймеру. В Kotlin для этого используют метод setBackgroundTintList(), который принимает объект ColorStateList.

val button = findViewById<Button>(R.id.myButton)
button.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#FF5722"))

Прямая установка через setBackgroundColor() на MaterialButton может привести к потере скруглений и эффекта пульсации (ripple). Поэтому правильнее использовать именно backgroundTintList. Для изменения цвета текста программно применяется метод setTextColor():

button.setTextColor(Color.parseColor("#FFFFFF"))

Способ 3: Глобальная настройка через темы

Если в приложении много кнопок и все они должны быть одного цвета, разумнее настроить тему один раз, чем прописывать атрибуты для каждой кнопки отдельно. Откройте файл res/values/themes.xml и добавьте в тему атрибут colorPrimary:

<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="colorPrimary">#2196F3</item>
    <item name="colorOnPrimary">#FFFFFF</item>
</style>

Теперь все кнопки, использующие стиль по умолчанию, будут синими с белым текстом. Атрибут colorPrimary задаёт основной цвет фона, а colorOnPrimary — цвет текста на этом фоне. Этот подход рекомендуют разработчики из Google, и он описан в официальной документации MaterialButton.

Однако если какая-то конкретная кнопка должна отличаться от общего стиля, её всё равно можно переопределить индивидуально через app:backgroundTint.


Способ 4: Селектор для разных состояний

Пользователь ожидает, что кнопка будет менять цвет при нажатии. Чтобы реализовать такое поведение, создают ColorStateList — XML-файл в папке res/color, который описывает разные цвета для разных состояний.

Создайте файл res/color/button_tint.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#FF5722" android:state_pressed="true" />
    <item android:color="#4CAF50" />
</selector>

Теперь подключите его к кнопке:

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Нажми меня"
    app:backgroundTint="@color/button_tint" />

При обычном состоянии кнопка будет зелёной, при нажатии — оранжевой. Можно добавить и другие состояния: state_enabled="false" для отключённой кнопки, state_focused="true" для кнопки в фокусе.


Программная установка ColorStateList

Если селектор нужно создать динамически, в Kotlin это делается через ColorStateList с двумя массивами: первый — состояния, второй — соответствующие им цвета.

val states = arrayOf(
    intArrayOf(android.R.attr.state_pressed),
    intArrayOf()
)
val colors = intArrayOf(
    Color.parseColor("#FF5722"), // оранжевый при нажатии
    Color.parseColor("#4CAF50")  // зелёный по умолчанию
)
val colorStateList = ColorStateList(states, colors)
button.backgroundTintList = colorStateList

Этот способ удобен, когда цвета зависят от данных, загруженных с сервера, или от пользовательских настроек. Он обеспечивает одинаковое поведение на всех версиях Android и корректно работает с тёмной темой.


Распространённые ошибки и их решение

При попытке поменять цвет кнопки начинающие разработчики часто сталкиваются с одними и теми же проблемами. Вот основные из них:

  • Кнопка не меняет цвет. Проверьте, что используется app:backgroundTint, а не android:background. Если проект создан в Android Studio 4.1 или новее, тема по умолчанию — Material Components, и она блокирует прямое изменение фона.
  • Цвет меняется, но пропали скругления. Вы применили setBackgroundColor() вместо setBackgroundTintList(). Первый метод заменяет весь фон, удаляя форму MaterialButton. Используйте backgroundTintList.
  • Цвет не меняется при нажатии. Если задать app:backgroundTint="@color/red" (ссылку на простой цвет, а не на ColorStateList), кнопка будет всегда одного цвета. Используйте селектор из папки res/color.
  • Не находится атрибут backgroundTint. Добавьте пространство имён xmlns:app="http://schemas.android.com/apk/res-auto" в корневой элемент разметки.

Что важно запомнить

Мы разобрали все основные способы того, как поменять цвет кнопки в android studio: через app:backgroundTint в XML, программно через setBackgroundTintList(), через глобальную тему и с помощью селекторов для разных состояний. Главное правило — для MaterialButton всегда используйте tint-атрибуты, а не прямой background. Это сохранит внешний вид кнопки и её интерактивные эффекты. Выберите подходящий способ под свою задачу и больше не тратьте время на борьбу с фиолетовыми кнопками по умолчанию.