Раскраски кнопок в Android с помощью Material Design и AppCompat
Перед AppCompat
Сегодня вышло обновление: мне удалось изменить цвет кнопок в Android L, но не на старых версиях. После включения нового обновления AppCompat я не могу изменить цвет для любой версии, когда я пытаюсь попробовать, кнопка просто исчезает. Кто-нибудь знает, как изменить цвет кнопки?
На следующих рисунках показано, чего я хочу достичь:
Белая кнопка по умолчанию, красная - то, что я хочу.
Это то, что я делал ранее, чтобы изменить цвет кнопок в styles.xml
:
<item name="android:colorButtonNormal">insert color here</item>
и сделать это динамически:
button.getBackground().setColorFilter(getResources().getColor(insert color here), PorterDuff.Mode.MULTIPLY);
Также я изменил родителя темы с @android:style/Theme.Material.Light.DarkActionBar
в Theme.AppCompat.Light.DarkActionBar
29 ответов
Официально исправлено в Библиотеке поддержки ред.22 (пт 13 марта 2015 г.). См. Соответствующую проблему кода Google:
https://issuetracker.google.com/issues/37008632
Пример использования
theme.xml:
<item name="colorButtonNormal">@color/button_color</item>
v21 / theme.xml
<item name="android:colorButtonNormal">@color/button_color</item>
Изменить (22.06.2016):
БиблиотекаAppcompat начала поддерживать кнопки материалов после того, как я опубликовал исходный ответ. В этом посте вы можете увидеть простейшую реализацию поднятых и плоских кнопок.
Оригинальный ответ:
Поскольку этот AppCompat не поддерживает кнопку, вы можете использовать xml в качестве фона. Для этого я взглянул на исходный код Android и нашел соответствующие файлы для оформления кнопок материалов.
1 - Посмотрите на оригинальную реализацию материала кнопки из источника.
Взгляните на btn_default_material.xml в исходном коде Android.
Вы можете скопировать файл в папку вашего проекта drawable-v21. Но не трогай цвет здесь. Файл, который нужно изменить, является вторым файлом.
вытяжка-V21 / custom_btn.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>
2 - Получить форму оригинального материала кнопкой
Как вы понимаете, внутри этого чертежа используется форма, которую вы можете найти в этом файле исходного кода.
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="?attr/colorButtonNormal" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
3 - Получение размеров кнопки материала
И в этом файле вы найдете некоторые измерения из файла, который вы можете найти здесь. Вы можете скопировать весь файл и поместить в папку с ценностями. Это важно для применения одинакового размера (который используется в кнопках материала) ко всем кнопкам
4 - Создайте еще один нарисованный файл для старых версий
Для более старых версий у вас должен быть другой drawable с тем же именем. Я непосредственно помещаю пункты в линию вместо ссылки. Вы можете ссылаться на них. Но, опять же, самое главное - это исходные размеры кнопки материала.
рисуем / custom_btn.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- pressed state -->
<item android:state_pressed="true">
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/PRESSED_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
<!-- focused state -->
<item android:state_focused="true">
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/FOCUSED_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
<!-- normal state -->
<item>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/button_inset_horizontal_material"
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<shape android:shape="rectangle">
<corners android:radius="@dimen/control_corner_material" />
<solid android:color="@color/NORMAL_STATE_COLOR" />
<padding android:left="@dimen/button_padding_horizontal_material"
android:top="@dimen/button_padding_vertical_material"
android:right="@dimen/button_padding_horizontal_material"
android:bottom="@dimen/button_padding_vertical_material" />
</shape>
</inset>
</item>
</selector>
Результат
Ваша кнопка будет иметь волновой эффект на устройствах Lollipop. Старые версии будут иметь точно такую же кнопку, кроме эффекта ряби. Но с тех пор, как вы предоставите рисованные элементы для разных состояний, они также будут реагировать на сенсорные события (как по старинке)
Это было улучшено в v23.0.0 библиотеки AppCompat с добавлением большего количества тем, включая
Widget.AppCompat.Button.Colored
Прежде всего, включите зависимость appCompat, если вы еще этого не сделали
compile('com.android.support:appcompat-v7:23.0.0') {
exclude group: 'com.google.android', module: 'support-v4'
}
теперь, так как вам нужно использовать v23 приложения-компата, вы должны будете также использовать SDK-v23!
compileSdkVersion = 23
targetSdkVersion = 23
В вашем values/theme
<item name="android:buttonStyle">@style/BrandButtonStyle</item>
В вашем values/style
<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@color/yourButtonColor</item>
<item name="android:textColor">@color/White</item>
</style>
В вашем values-v21/style
<style name="BrandButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="android:colorButtonNormal">@color/yourButtonColor</item>
<item name="android:textColor">@color/White</item>
</style>
Так как ваша тема кнопки основана на Widget.AppCompat.Button.Colored
Цвет текста на кнопке по умолчанию белый!
но, кажется, есть проблема, когда вы отключаете кнопку, кнопка изменит свой цвет на светло-серый, но цвет текста останется белым!
Обходной путь для этого - специально установить цвет текста на кнопке белым! как я сделал в стиле, показанном выше.
теперь вы можете просто определить свою кнопку и позволить AppCompat сделать все остальное:)
<Button
android:layout_width="200dp"
android:layout_height="48dp" />
В библиотеке поддержки Android 22.1.0 Google сделал Button
тонировка в курсе. Итак, еще один способ настроить цвет фона кнопки - это использовать backgroundTint
приписывать.
Например,
<Button
android:id="@+id/add_remove_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/bg_remove_btn_default"
android:textColor="@android:color/white"
tools:text="Remove" />
Для поддержки цветных кнопок используйте последнюю библиотеку AppCompat (>23.2.1) с:
раздувать - XML
AppCompat Widget:
android.support.v7.widget.AppCompatButton
Стиль AppCompat:
style="@style/Widget.AppCompat.Button.Colored"
NB! Чтобы установить собственный цвет в xml: используйте attr: app
вместо android
(использование alt+enter
или объявить xmlns:app="http://schemas.android.com/apk/res-auto"
использовать app
)
app: backgroundTint = "@ color / your_custom_color"
Пример:
<android.support.v7.widget.AppCompatButton
style="@style/Widget.AppCompat.Button.Colored"
app:backgroundTint="@color/your_custom_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Colored Button"/>
или установите его программно - JAVA
ViewCompat.setBackgroundTintList(your_colored_button,
ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
С последней библиотекой поддержки вы можете просто унаследовать свою деятельность от AppCompatActivity
, так это будет раздувать ваш Button
как AppCompatButton
и дать вам возможность стилизовать цвет каждой кнопки на макете с помощью android:theme="@style/SomeButtonStyle"
, где SomeButtonStyle
является:
<style name="SomeButtonStyle" parent="@android:style/Widget.Button">
<item name="colorButtonNormal">@color/example_color</item>
</style>
Работал у меня в 2.3.7, 4.4.1, 5.0.2
Если вы хотите ниже стиля
добавить этот стиль вашей кнопки
style="@style/Widget.AppCompat.Button.Borderless.Colored"
если вы хотите этот стиль
добавить код ниже
style="@style/Widget.AppCompat.Button.Colored"
Ответ в ТЕМЕ, а не в стиле
Проблема в том, что цвет кнопки соответствует цвету кнопки нормального темы. Я пытался изменить стиль разными способами, но безуспешно. Поэтому я изменил тему кнопки.
Создайте тему с помощью colorButtonNormal и colorPrimary:
<style name="ThemeAwesomeButtonColor" parent="AppTheme">
<item name="colorPrimary">@color/awesomePrimaryColor</item>
<item name="colorButtonNormal">@color/awesomeButtonColor</item>
</style>
Используйте эту тему в кнопке
<Button
android:id="@+id/btn_awesome"
style="@style/AppTheme.Button"
android:theme="@style/ThemeAwesomeButtonColor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/btn_awesome"/>
"AppTheme.Button" может быть любой вещью, расширяющей стиль кнопки, как здесь, я использую основной цвет для цвета текста:
<style name="AppTheme.Button" parent="Base.Widget.AppCompat.Button">
...
<item name="android:textColor">?attr/colorPrimary</item>
...
</style>
И вы получите кнопку в любом цвете, который вы хотите, который совместим с дизайном материала.
Планировка:
<android.support.v7.widget.AppCompatButton
style="@style/MyButton"
...
/>
styles.xml:
<style name="MyButton" parent="Widget.AppCompat.Button.Colored">
<item name="backgroundTint">@color/button_background_selector</item>
<item name="android:textColor">@color/button_text_selector</item>
</style>
цвет /button_background_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#555555"/>
<item android:color="#00ff00"/>
</selector>
цвет /button_text_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#888888"/>
<item android:color="#ffffff"/>
</selector>
Это работает для меня с appcompat-v7:22.2.0 в Android + 4.0
в вашем styles.xml
<style name="Button.Tinted" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">YOUR_TINT_COLOR</item>
<item name="colorControlHighlight">@color/colorAccent</item>
<item name="android:textColor">@android:color/white</item>
</style>
в вашем файле макета
<Button
android:id="@+id/but_next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/but_continue"
android:theme="@style/Button.Tinted" />
Я только что создал библиотеку Android, которая позволяет легко изменять цвет кнопки и цвет пульсации
https://github.com/xgc1986/RippleButton
<com.xgc1986.ripplebutton.widget.RippleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
android:text="Android button modified in layout"
android:textColor="@android:color/white"
app:buttonColor="@android:color/black"
app:rippleColor="@android:color/white"/>
Вам не нужно создавать стиль для каждой нужной кнопки с другим цветом, что позволяет настраивать цвета случайным образом
Если вы используете стилевое решение с colorButtonNormal, не забудьте наследовать от Widget.AppCompat.Button.Colored, чтобы эффект ряби работал;)
подобно
<style name="CustomButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="colorButtonNormal">@android:color/white</item>
</style>
Для тех, кто использует ImageButton
вот как вы это делаете:
В style.xml:
<style name="BlueImageButton" parent="Base.Widget.AppCompat.ImageButton">
<item name="colorButtonNormal">@color/primary</item>
<item name="android:tint">@color/white</item>
</style>
в v21/style.xml:
<style name="BlueImageButton" parent="Widget.AppCompat.ImageButton">
<item name="android:colorButtonNormal">@color/primary</item>
<item name="android:tint">@color/white</item>
</style>
Тогда в вашем файле макета:
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/my_button"
android:theme="@style/BlueImageButton"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_check_black_24dp"
/>
Еще одно простое решение с использованием AppCompatButton
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.Button.Colored"
app:backgroundTint="@color/red"
android:text="UNINSTALL" />
Я использую это. Эффект ряби и работа тени при нажатии кнопки.
style.xml
<style name="Button.Red" parent="Widget.AppCompat.Button.Colored">
<item name="android:textColor">@color/material_white</item>
<item name="android:backgroundTint">@color/red</item>
</style>
Кнопка на макете:
<Button
style="@style/Button.Red"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/close"/>
Используйте android:backgroundTint="@color/customColor", и это придаст цвет кнопке. Все просто.
Чтобы изменить цвет одной кнопки
ViewCompat.setBackgroundTintList(button, getResources().getColorStateList(R.color.colorId));
Один из способов сделать это позволяет вам указать на стиль, а НЕ на тему ВСЕХ кнопок в вашем приложении.
В themes.xml добавить тему
<style name="Theme.MyApp.Button.Primary.Blue" parent="Widget.AppCompat.Button">
<item name="colorButtonNormal">@color/someColor</item>
<item name="android:textColorPrimary">@android:color/white</item>
</style>
Сейчас в styles.xml добавлю
<style name="MyApp.Button.Primary.Blue" parent="">
<item name="android:theme">@style/Theme.MyApp.Button.Primary.Blue</item>
</style>
Теперь в вашем макете просто укажите СТИЛЬ в вашей кнопке
<Button
...
style="@style/MyApp.Button.Primary.Blue"
... />
ОБНОВИТЬ
Используйте библиотеку поддержки дизайна (23.2.0) и appcompatwidgets, как показано ниже
В библиотеке поддержки Android 22.1:
Это делается автоматически при накачивании макетов - замена Button на AppCompatButton, TextView на AppCompatTextView и т. Д., Чтобы каждый из них мог поддерживать тонирование. В этом выпуске эти виджеты с поддержкой оттенков теперь общедоступны, что позволяет поддерживать поддержку оттенков даже в том случае, если вам нужно создать подкласс одного из поддерживаемых виджетов.
Полный список виджетов с оттенком:
AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView
Дизайн материала для устройств перед леденцом на палочке:
AppCompat (также известный как ActionBarCompat) начинался как бэкпорт API-интерфейса ActionBar для Android 4.0 для устройств, работающих на Gingerbread, предоставляя общий уровень API поверх реализации с обратным портированием и реализации платформы. AppCompat v21 предоставляет API и набор функций, актуальный для Android 5.0
Если вам нужна только кнопка "Плоский" материал, вы можете настроить их фон, используя атрибут selectableItemBackground, как описано здесь.
Если вы хотите использовать стиль AppCompat, такой как Widget.AppCompat.Button, Base.Widget.AppCompat.Button.Colored и т. Д., Вам необходимо использовать эти стили с совместимыми представлениями из библиотеки поддержки.
Приведенный ниже код не работает для устройств, предшествующих lolipop:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.Button" />
Вам необходимо использовать AppCompatButton для включения стилей AppCompat:
<android.support.v7.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/Widget.AppCompat.Button" />
Для меня проблема заключалась в том, что в Android 5.0 android:colorButtonNormal
не имеет никакого эффекта, и на самом деле, нет элемента из темы (как android:colorAccent
), но в Android 4.4.3, например, сделал. Проект был настроен с compileSdkVersion
а также targetSdkVersion
до 22, поэтому я внес все изменения как @Muhammad Alfaifi sugessted, но в конце я заметил, что проблема заключалась в buildToolsVersion, который не был обновлен. Как только я перешел на 23.0.1, все начинает работать почти как обычно. Теперь android:colorButtonNormal
все еще не имеет никакого эффекта, но по крайней мере кнопка реагирует на android:colorAccent
, что для меня приемлемо.
Я надеюсь, что этот намек может кому-то помочь. Примечание: я применил стиль непосредственно к кнопке, так как кнопка android:theme=[...]
также не имел эффекта.
Этот ТАК ответ помог мне прийти к ответу /questions/5709131/ispolzovanie-klassa-drawablecompat-dlya-primeneniya-tintlist/5709141#5709141
Я использую этот метод утилиты, чтобы установить фоновый оттенок кнопки. Работает с устройствами перед леденцом на палочке:
// Set button background tint programmatically so it is compatible with pre-lollipop devices.
public static void setButtonBackgroundTintAppCompat(Button button, ColorStateList colorStateList){
Drawable d = button.getBackground();
if (button instanceof AppCompatButton) {
// appcompat button replaces tint of its drawable background
((AppCompatButton)button).setSupportBackgroundTintList(colorStateList);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Lollipop button replaces tint of its drawable background
// however it is not equal to d.setTintList(c)
button.setBackgroundTintList(colorStateList);
} else {
// this should only happen if
// * manually creating a Button instead of AppCompatButton
// * LayoutInflater did not translate a Button to AppCompatButton
d = DrawableCompat.wrap(d);
DrawableCompat.setTintList(d, colorStateList);
button.setBackgroundDrawable(d);
}
}
Как использовать в коде:
Utility.setButtonBackgroundTintAppCompat(myButton,
ContextCompat.getColorStateList(mContext, R.color.your_custom_color));
Таким образом, вам не нужно указывать ColorStateList, если вы просто хотите изменить оттенок фона и ничего более, кроме того, чтобы поддерживать приятные эффекты кнопок, а что нет.
Если вы хотите сделать это с помощью кода любого цвета, используйте это:
DrawableCompat.setTintList(button.getBackground(), ColorStateList.valueOf(yourColor));
Я на самом деле не хотел изменений в моих пользовательских стилях кнопок, но, к сожалению, они больше не работали.
У моего приложения minSdkVersion 9, и все работало раньше.
Я не знаю почему, но так как я удалил Android: до buttonStyle, кажется, снова работает
сейчас = работает:
<item name="buttonStyle">@style/ButtonmyTime</item>
до = только серые кнопки материала:
<item name="android:buttonStyle">@style/ButtonmyTime</item>
У меня нет специальной папки для новой версии Android, так как мои кнопки довольно плоские, и они должны выглядеть одинаково на всех версиях Android.
Может быть, кто-то может сказать мне, почему я должен был удалить "android:" ImageButton все еще работает с "android:"
<item name="android:imageButtonStyle">@style/ImageButtonmyTimeGreen</item>
В моем случае вместо кнопки я использую androidx.appcompat.widget.AppCompatButton, и у меня это сработало.
Я поставил android:textColor
в @null
в моей теме кнопки, и это помогает.
styles.xml
<style name="Button.Base.Borderless" parent="Widget.AppCompat.Button.Borderless.Colored">
<item name="android:textColor">@null</item>
</style>
some_layout.xml
<Button
style="@style/Button.Base.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hint" />
Теперь цвет текста кнопки colorAccent
определяется в AppTheme
<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">@color/colorAccent</item>
<item name="borderlessButtonStyle">@style/Button.Base.Borderless</item>
<item name="alertDialogTheme">@style/AlertDialog</item>
</style>
Если вы используете kotlin, вы видите, что все атрибуты из MaterialButton поддерживаются. Не используйте атрибут android: background. MaterialButton управляет своим собственным фоном, доступным для рисования, и установка нового фона означает, что отключенный цвет кнопки материала больше не может гарантировать, что новые атрибуты, которые он вводит, будут работать правильно. Если фон по умолчанию изменен, кнопка материала не может гарантировать четко определенного поведения.На MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buttonClick.setOnClickListener {
(it as MaterialButton).apply {
backgroundTintList = ColorStateList.valueOf(Color.YELLOW)
backgroundTintMode = PorterDuff.Mode.SRC_ATOP
}
}
}
}
На activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/constraintLayout"
tools:context=".MainActivity">
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Material Button Normal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonTint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:backgroundTint="#D3212D"
android:text="Material Button Background Red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonNormal" />
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonTintMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:backgroundTint="#D3212D"
android:backgroundTintMode="multiply"
android:text="Tint Red + Mode Multiply"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonTint" />
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Click To Change Background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buttonTintMode" />
</androidx.constraintlayout.widget.ConstraintLayout>
После 2 дней поиска ответов у меня не работала тема кнопок в API < 21.
Мое единственное решение состоит в том, чтобы переопределить тонирование AppCompatButton не только с основной темой приложения "colorButtonNormal", но и с видом backgroundTint следующим образом:
public class AppCompatColorButton extends AppCompatButton {
public AppCompatColorButton(Context context) {
this(context, null);
}
public AppCompatColorButton(Context context, AttributeSet attrs) {
this(context, attrs, android.support.v7.appcompat.R.attr.buttonStyle);
}
public AppCompatColorButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (TintManager.SHOULD_BE_USED) {
setSupportBackgroundTintList(createButtonColorStateList(getContext(), attrs, defStyleAttr));
}
}
static final int[] DISABLED_STATE_SET = new int[]{-android.R.attr.state_enabled};
static final int[] FOCUSED_STATE_SET = new int[]{android.R.attr.state_focused};
static final int[] PRESSED_STATE_SET = new int[]{android.R.attr.state_pressed};
static final int[] EMPTY_STATE_SET = new int[0];
private ColorStateList createButtonColorStateList(Context context, AttributeSet attrs, int defStyleAttr) {
final int[][] states = new int[4][];
final int[] colors = new int[4];
int i = 0;
final int themeColorButtonNormal = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
/*TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.backgroundTint }, defStyleAttr, 0);
final int colorButtonNormal = a.getColor(0, themeColorButtonNormal);*/
TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.View, defStyleAttr, 0);
final int colorButtonNormal = a.getColor(android.support.v7.appcompat.R.styleable.View_backgroundTint, themeColorButtonNormal);
a.recycle();
final int colorControlHighlight = ThemeUtils.getThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorControlHighlight);
// Disabled state
states[i] = DISABLED_STATE_SET;
colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, android.support.v7.appcompat.R.attr.colorButtonNormal);
i++;
states[i] = PRESSED_STATE_SET;
colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
i++;
states[i] = FOCUSED_STATE_SET;
colors[i] = ColorUtils.compositeColors(colorControlHighlight, colorButtonNormal);
i++;
// Default enabled state
states[i] = EMPTY_STATE_SET;
colors[i] = colorButtonNormal;
i++;
return new ColorStateList(states, colors);
}
}
Затем вы можете определить свой цвет кнопки следующим образом:
<com.example.views.AppCompatColorButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#ffff0000"
app:backgroundTint="#ffff0000"
android:text="Button"
android:textColor="@android:color/white" />