5 проверенных способов изменить цвет Floating Action Button в Android

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Android-разработчики, стремящиеся улучшить интерфейс своих приложений
  • Ученики и студенты курсов по программированию, заинтересованные в разработке мобильных приложений
  • Дизайнеры интерфейсов, желающие узнать больше о кастомизации элементов Material Design

    Floating Action Button — фирменный элемент Material Design, который давно стал визитной карточкой Android-приложений. Яркая круглая кнопка с тенью, парящая над интерфейсом, привлекает внимание и указывает на главное действие. Но стандартный цвет FAB не всегда вписывается в вашу цветовую схему или брендинг. Недавно я разрабатывал финансовое приложение, где фиолетовый FAB выглядел чужеродно на фоне корпоративных синих оттенков. Пришлось освоить все методы кастомизации этого элемента. Поделюсь пятью рабочими способами изменить цвет FAB, чтобы сделать его гармоничной частью вашего UI. 🎨

Хотите стать Android-разработчиком с нуля? Курс Java-разработки от Skypro — ваш путь к созданию профессиональных мобильных приложений. От основ Java до продвинутых UI-компонентов вроде Floating Action Button. Студенты курса создают реальные проекты под руководством практикующих разработчиков. Бонус: модуль по Material Design и созданию адаптивного интерфейса для Android-приложений.

Что такое FAB и зачем менять его цвет в Android UI

Floating Action Button (FAB) — это круглая кнопка с иконкой, которая "парит" над интерфейсом приложения и представляет основное действие на экране. Компонент является частью библиотеки Material Design от Google и призван обеспечивать интуитивно понятный доступ к главной функции экрана.

Стандартный FAB имеет фиксированные параметры стиля, включая цвет фона, который по умолчанию наследуется от colorAccent или colorSecondary в теме приложения. Однако существует множество сценариев, когда требуется изменить его цветовую схему:

  • Соответствие брендингу компании и фирменному стилю
  • Улучшение контраста для повышения доступности приложения
  • Создание визуальной иерархии, где разные цвета FAB указывают на разные типы действий
  • Реализация динамических изменений цвета для обозначения различных состояний
  • Обеспечение визуальной гармонии с остальными элементами интерфейса

Дмитрий Карпов, Senior Android Developer

Работая над банковским приложением, мы столкнулись с нетривиальной задачей — FAB должен был менять цвет в зависимости от баланса счёта. Зелёный для положительного баланса, жёлтый для околонулевого и красный для отрицательного. Изначально я использовал самый простой подход с XML, но быстро понял его ограниченность.

Пришлось перейти к программному изменению цвета, что позволило динамически реагировать на данные. Клиенты начали замечать этот небольшой визуальный индикатор: "О, кнопка покраснела — пора пополнять счёт!" Этот простой UX-приём значительно увеличил своевременность пополнений счетов и снизил количество уходов в овердрафт на 17%.

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

Элемент FAB Описание Свойство для изменения цвета
Фон Основной круглый элемент кнопки backgroundTint
Иконка Графическое изображение в центре tint (для векторных drawable)
Рипл-эффект Анимация при нажатии rippleColor
Тень Тень под кнопкой для эффекта "парения" elevation, pressedTranslationZ

Теперь рассмотрим пять проверенных способов изменения цвета FAB, начиная от самых простых до продвинутых техник. 🚀

Пошаговый план для смены профессии

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

Самый базовый и часто используемый подход к изменению цвета FAB — использование XML-атрибутов. Этот способ идеально подходит, когда цвет кнопки должен быть статическим и определен заранее.

Для начала убедитесь, что в вашем проекте подключена библиотека Material Components:

groovy
Скопировать код
implementation 'com.google.android.material:material:1.9.0'

Теперь можно создать FAB в макете с нужным цветом:

xml
Скопировать код
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:contentDescription="@string/add_item"
app:backgroundTint="@color/custom_blue"
app:srcCompat="@drawable/ic_add" />

Ключевой атрибут здесь — app:backgroundTint, который управляет цветом фона кнопки. Вы можете указать конкретный цвет или ссылку на ресурс цвета из вашего файла colors.xml:

xml
Скопировать код
<!-- colors.xml -->
<resources>
<color name="custom_blue">#3F51B5</color>
<color name="custom_green">#4CAF50</color>
<color name="custom_orange">#FF9800</color>
</resources>

Для более тонкой настройки можно использовать селектор состояний, который позволяет определять разные цвета для разных состояний кнопки:

xml
Скопировать код
<!-- fab_color_selector.xml в каталоге res/color -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/custom_blue_dark" android:state_pressed="true" />
<item android:color="@color/custom_blue" />
</selector>

Затем используйте селектор как значение backgroundTint:

xml
Скопировать код
app:backgroundTint="@color/fab_color_selector"

Если вам нужно изменить цвет иконки FAB, используйте атрибут app:tint для векторных иконок:

xml
Скопировать код
app:tint="@color/white"

Или установите цвет непосредственно в векторном drawable:

xml
Скопировать код
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="@color/white"
... >

Преимущества и недостатки использования XML-атрибутов:

  • ✅ Простота реализации — минимальный код
  • ✅ Наглядность — все стили видны в XML макете
  • ✅ Производительность — статические стили обрабатываются быстрее
  • ❌ Отсутствие динамичности — сложно менять цвета в рантайме
  • ❌ Ограниченность — некоторые эффекты требуют программного подхода

Способ 2: Программное изменение цвета FAB через код

Когда требуется динамически менять цвет FAB в ответ на действия пользователя или изменения данных, программное управление цветом становится незаменимым. Рассмотрим, как изменять цвет FAB через код на Java и Kotlin.

Алексей Смирнов, Lead Android Developer

В моём приложении для фитнеса пользователи жаловались на отсутствие понятной индикации режимов тренировки. У нас было три режима: кардио, силовая и растяжка. Переключались между ними через FAB, но не было понятно, какой режим активен.

Решил динамически менять цвет FAB: красный для кардио, синий для силовой и зелёный для растяжки. Используя программное изменение цвета, реализовал не только смену основного цвета, но и плавный переход между оттенками.

Результат превзошёл ожидания — количество ошибочных выборов режима упало на 78%, а средний рейтинг приложения вырос с 4.2 до 4.7. Пользователи особенно хвалили "интуитивность интерфейса" и "понятную цветовую индикацию". Никто не догадывался, что решение было реализовано буквально за час.

Java-реализация:

Java
Скопировать код
FloatingActionButton fab = findViewById(R.id.fab);

// Изменение цвета фона
fab.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#FF4081")));

// Изменение цвета иконки
fab.setImageTintList(ColorStateList.valueOf(Color.WHITE));

// Изменение цвета эффекта пульсации (ripple)
fab.setRippleColor(ColorStateList.valueOf(Color.parseColor("#B3FF4081")));

Kotlin-реализация:

kotlin
Скопировать код
val fab: FloatingActionButton = findViewById(R.id.fab)

// Изменение цвета фона
fab.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#FF4081"))

// Изменение цвета иконки
fab.imageTintList = ColorStateList.valueOf(Color.WHITE)

// Изменение цвета эффекта пульсации (ripple)
fab.rippleColor = ColorStateList.valueOf(Color.parseColor("#B3FF4081"))

Для работы с цветами из ресурсов используйте:

Java
Скопировать код
// Java
fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.custom_blue)));

// Kotlin
fab.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.custom_blue))

Обратите внимание на различия между методами установки цвета:

Метод Применение API Level Особенности
setBackgroundTintList() Изменение цвета фона FAB 21+ Основной метод для Material Components
setBackgroundColor() Не рекомендуется для FAB Все Может сломать эффект тени и форму FAB
setColorFilter() Устаревший метод для иконок Все (устаревший) Заменён на setImageTintList
setImageTintList() Изменение цвета иконки 21+ Работает только с векторными drawable

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

Java
Скопировать код
// Java
int[][] states = new int[][] {
new int[] { android.R.attr.state_pressed }, // Pressed state
new int[] { } // Default state
};

int[] colors = new int[] {
ContextCompat.getColor(this, R.color.custom_blue_dark), // Pressed color
ContextCompat.getColor(this, R.color.custom_blue) // Default color
};

ColorStateList colorStateList = new ColorStateList(states, colors);
fab.setBackgroundTintList(colorStateList);

// Kotlin
val states = arrayOf(
intArrayOf(android.R.attr.state_pressed), // Pressed state
intArrayOf() // Default state
)

val colors = intArrayOf(
ContextCompat.getColor(this, R.color.custom_blue_dark), // Pressed color
ContextCompat.getColor(this, R.color.custom_blue) // Default color
)

val colorStateList = ColorStateList(states, colors)
fab.backgroundTintList = colorStateList

Преимущества программного изменения цвета:

  • ✅ Гибкость — можно менять цвета в ответ на любые события
  • ✅ Динамичность — поддержка изменения цветов во время выполнения
  • ✅ Больше контроля — возможность создавать сложные селекторы программно
  • ❌ Больше кода по сравнению с XML-подходом
  • ❌ Сложнее отлаживать визуальные эффекты

Способ 3: Создание анимации и переходов цвета FAB

Плавные цветовые переходы могут существенно улучшить UX вашего приложения, делая интерфейс более живым и отзывчивым. В Android есть несколько способов анимировать изменение цвета FAB. 🎭

Начнем с простого примера использования ValueAnimator для плавного перехода между двумя цветами:

Java
Скопировать код
// Java
private void animateFabColor(FloatingActionButton fab, int colorFrom, int colorTo) {
ValueAnimator colorAnimation = ValueAnimator.ofObject(
new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(300); // 300ms для плавного перехода

colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
fab.setBackgroundTintList(
ColorStateList.valueOf((int) animator.getAnimatedValue()));
}
});

colorAnimation.start();
}

// Пример использования
animateFabColor(fab, 
ContextCompat.getColor(this, R.color.custom_blue),
ContextCompat.getColor(this, R.color.custom_green));

// Kotlin
private fun animateFabColor(fab: FloatingActionButton, colorFrom: Int, colorTo: Int) {
val colorAnimation = ValueAnimator.ofObject(
ArgbEvaluator(), colorFrom, colorTo)
colorAnimation.duration = 300 // 300ms для плавного перехода

colorAnimation.addUpdateListener { animator ->
fab.backgroundTintList = ColorStateList.valueOf(
animator.animatedValue as Int)
}

colorAnimation.start()
}

Для более сложных анимаций можно использовать ObjectAnimator или AnimatorSet:

Java
Скопировать код
// Java
private void pulseFabColor(FloatingActionButton fab, int colorNormal, int colorHighlight) {
ObjectAnimator colorFade = ObjectAnimator.ofObject(
fab, 
"backgroundTintList",
new ArgbEvaluatorHolder(), 
ColorStateList.valueOf(colorNormal),
ColorStateList.valueOf(colorHighlight));

colorFade.setDuration(500);
colorFade.setRepeatCount(1);
colorFade.setRepeatMode(ValueAnimator.REVERSE);
colorFade.start();
}

// Класс-адаптер для работы с ColorStateList в ObjectAnimator
public class ArgbEvaluatorHolder implements TypeEvaluator<ColorStateList> {
private final ArgbEvaluator evaluator = new ArgbEvaluator();

@Override
public ColorStateList evaluate(float fraction, ColorStateList startValue, 
ColorStateList endValue) {
int color = (int) evaluator.evaluate(fraction, 
startValue.getDefaultColor(), 
endValue.getDefaultColor());
return ColorStateList.valueOf(color);
}
}

// Kotlin
private fun pulseFabColor(fab: FloatingActionButton, colorNormal: Int, colorHighlight: Int) {
val colorFade = ObjectAnimator.ofObject(
fab, 
"backgroundTintList",
ArgbEvaluatorHolder(), 
ColorStateList.valueOf(colorNormal),
ColorStateList.valueOf(colorHighlight))

colorFade.duration = 500
colorFade.repeatCount = 1
colorFade.repeatMode = ValueAnimator.REVERSE
colorFade.start()
}

// Класс-адаптер для работы с ColorStateList в ObjectAnimator
class ArgbEvaluatorHolder : TypeEvaluator<ColorStateList> {
private val evaluator = ArgbEvaluator()

override fun evaluate(fraction: Float, startValue: ColorStateList, 
endValue: ColorStateList): ColorStateList {
val color = evaluator.evaluate(
fraction, 
startValue.defaultColor, 
endValue.defaultColor) as Int
return ColorStateList.valueOf(color)
}
}

Еще один мощный способ анимации — использование Motion Layout, который позволяет создавать сложные анимации с минимальным кодом:

xml
Скопировать код
<!-- motion_scene.xml -->
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">

<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="500">
<OnClick
motion:targetId="@id/fab"
motion:clickAction="toggle" />

<KeyFrameSet>
<KeyAttribute
motion:framePosition="0"
motion:target="@id/fab"
motion:transitionEasing="decelerate"
android:backgroundTint="@color/custom_blue" />

<KeyAttribute
motion:framePosition="100"
motion:target="@id/fab"
motion:transitionEasing="accelerate"
android:backgroundTint="@color/custom_green" />
</KeyFrameSet>
</Transition>

<ConstraintSet android:id="@+id/start">
<!-- Начальные ограничения -->
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
<!-- Конечные ограничения -->
</ConstraintSet>
</MotionScene>

Для создания непрерывного "дышащего" эффекта с изменением цвета можно использовать бесконечную анимацию:

Java
Скопировать код
// Java
private void startBreathingAnimation(FloatingActionButton fab) {
ObjectAnimator colorAnimator = ObjectAnimator.ofArgb(
fab, 
"backgroundTint", 
Color.RED, 
Color.BLUE);

colorAnimator.setDuration(2000);
colorAnimator.setRepeatCount(ObjectAnimator.INFINITE);
colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
colorAnimator.setEvaluator(new ArgbEvaluator());
colorAnimator.start();
}

// Kotlin
private fun startBreathingAnimation(fab: FloatingActionButton) {
val colorAnimator = ObjectAnimator.ofArgb(
fab, 
"backgroundTint", 
Color.RED, 
Color.BLUE)

colorAnimator.duration = 2000
colorAnimator.repeatCount = ObjectAnimator.INFINITE
colorAnimator.repeatMode = ValueAnimator.REVERSE
colorAnimator.setEvaluator(ArgbEvaluator())
colorAnimator.start()
}

Варианты применения анимации цвета FAB:

  • Индикация прогресса длительной операции
  • Привлечение внимания к новым функциям
  • Визуализация смены состояния (например, запись → пауза)
  • Подтверждение успешного действия (мигание зеленым)
  • Предупреждение об ошибке (пульсация красным)

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

В Material Design FAB может находиться в различных состояниях: нормальное, нажатое, отключенное и т.д. Для каждого из этих состояний можно задать свой цвет, создавая более отзывчивый и информативный интерфейс. 🎨

Рассмотрим, как реализовать разные цвета FAB для разных состояний активности.

Вариант 1: Использование селектора состояний в XML

Создадим файл селектора цветов в папке res/color:

xml
Скопировать код
<!-- res/color/fab_color_state_list.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/fab_disabled" android:state_enabled="false" />
<item android:color="@color/fab_pressed" android:state_pressed="true" />
<item android:color="@color/fab_focused" android:state_focused="true" android:state_enabled="true" />
<item android:color="@color/fab_normal" /> <!-- Default state -->
</selector>

Теперь используем этот селектор в нашем FAB:

xml
Скопировать код
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
app:backgroundTint="@color/fab_color_state_list"
app:srcCompat="@drawable/ic_add" />

Аналогично можно создать селектор для цвета иконки:

xml
Скопировать код
<!-- res/color/fab_icon_color_state_list.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/icon_disabled" android:state_enabled="false" />
<item android:color="@color/icon_normal" />
</selector>

И применить его:

xml
Скопировать код
app:tint="@color/fab_icon_color_state_list"

Вариант 2: Программное создание селектора состояний

Java
Скопировать код
// Java
private void setFabStateColors(FloatingActionButton fab) {
int[][] states = new int[][] {
new int[] { -android.R.attr.state_enabled }, // Disabled state
new int[] { android.R.attr.state_pressed }, // Pressed state
new int[] { android.R.attr.state_focused }, // Focused state
new int[] { } // Default state
};

int[] colors = new int[] {
Color.GRAY, // Disabled color
Color.parseColor("#A52A2A"), // Pressed color (Brown)
Color.parseColor("#FFA500"), // Focused color (Orange)
Color.parseColor("#1E90FF") // Default color (Dodger Blue)
};

ColorStateList colorStateList = new ColorStateList(states, colors);
fab.setBackgroundTintList(colorStateList);
}

// Kotlin
private fun setFabStateColors(fab: FloatingActionButton) {
val states = arrayOf(
intArrayOf(-android.R.attr.state_enabled), // Disabled state
intArrayOf(android.R.attr.state_pressed), // Pressed state
intArrayOf(android.R.attr.state_focused), // Focused state
intArrayOf() // Default state
)

val colors = intArrayOf(
Color.GRAY, // Disabled color
Color.parseColor("#A52A2A"), // Pressed color (Brown)
Color.parseColor("#FFA500"), // Focused color (Orange)
Color.parseColor("#1E90FF") // Default color (Dodger Blue)
)

val colorStateList = ColorStateList(states, colors)
fab.backgroundTintList = colorStateList
}

Для более полного контроля над внешним видом FAB в разных состояниях, можно определить стиль в themes.xml:

xml
Скопировать код
<!-- themes.xml -->
<style name="CustomFabStyle" parent="Widget.MaterialComponents.FloatingActionButton">
<item name="backgroundTint">@color/fab_color_state_list</item>
<item name="tint">@color/fab_icon_color_state_list</item>
<item name="rippleColor">@color/fab_ripple_color_state_list</item>
<item name="elevation">6dp</item>
<item name="pressedTranslationZ">12dp</item>
</style>

И применить его к FAB:

xml
Скопировать код
<com.google.android.material.floatingactionbutton.FloatingActionButton
style="@style/CustomFabStyle"
... />

Состояния FAB, которые можно стилизовать:

Состояние XML атрибут Примечание
Нормальное По умолчанию (без атрибутов) Основное состояние кнопки
Нажатое android:state_pressed="true" Когда пользователь нажимает на кнопку
Отключенное android:state_enabled="false" Когда кнопка неактивна (fab.setEnabled(false))
В фокусе android:state_focused="true" Когда кнопка получает фокус ввода
Выбранное android:state_selected="true" Для состояния выбора (fab.setSelected(true))
Активированное android:state_activated="true" Особое состояние активации (fab.setActivated(true))

Для реагирования на изменения состояний можно также использовать слушатели:

Java
Скопировать код
// Java
fab.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Изменение цвета при нажатии
fab.setBackgroundTintList(
ColorStateList.valueOf(Color.parseColor("#A52A2A")));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Возврат к исходному цвету
fab.setBackgroundTintList(
ColorStateList.valueOf(Color.parseColor("#1E90FF")));
break;
}
// Возвращаем false, чтобы стандартный обработчик onClick тоже сработал
return false;
}
});

// Kotlin
fab.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
// Изменение цвета при нажатии
fab.backgroundTintList = 
ColorStateList.valueOf(Color.parseColor("#A52A2A"))
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
// Возврат к исходному цвету
fab.backgroundTintList = 
ColorStateList.valueOf(Color.parseColor("#1E90FF"))
}
}
// Возвращаем false, чтобы стандартный обработчик onClick тоже сработал
false
}

Такой подход к стилизации FAB для различных состояний позволяет создавать более интерактивные и отзывчивые интерфейсы, что значительно улучшает UX вашего приложения. 🚀

Изменение цвета Floating Action Button — это мощный инструмент для улучшения пользовательского опыта, который выходит далеко за рамки простой эстетики. Правильно подобранные цвета и анимации превращают FAB из простой кнопки в интуитивный коммуникационный канал между приложением и пользователем. Не ограничивайтесь базовыми настройками — экспериментируйте с состояниями, переходами и анимациями. В конечном счете, именно такие небольшие детали делают ваше приложение запоминающимся и выделяют его среди конкурентов.

Загрузка...