Влияние материала на кнопку с цветом фона

Я использую библиотеку поддержки Android v21.

Я создал кнопку с пользовательским цветом фона. Эффекты материала, такие как пульсация, раскрытие исчезают (кроме высоты над щелчком), когда я использую задний цвет земли.

 <Button
 style="?android:attr/buttonStyleSmall"
 android:background="?attr/colorPrimary"
 android:textColor="@color/white"
 android:textAllCaps="true"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 />

Background Следующая нормальная кнопка, и эффекты работают нормально.

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textAllCaps="true"
 android:text="Button1"
/>

Default button

Ответ 1

Когда вы используете android:background, вы заменяете большую часть стиля и внешнего вида кнопки с пустым цветом.

Обновление: В разделе версии 23.0.0 AppCompat существует новый стиль Widget.AppCompat.Button.Colored, который использует вашу тему colorButtonNormal для отключенного цвета и colorAccent для разрешенного цвета.

Это позволяет применить его к вашей кнопке напрямую через

<Button
  ...
  style="@style/Widget.AppCompat.Button.Colored" />

Если вам нужен пользовательский colorButtonNormal или colorAccent, вы можете использовать ThemeOverlay, как описано в этом проконтакте и android:theme на кнопка.

Предыдущий ответ

Вы можете использовать drawable в своем каталоге v21 для вашего фона, например:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:drawable="?attr/colorPrimary"/>
</ripple>

Это гарантирует, что цвет фона ?attr/colorPrimary и имеет анимацию пульсации по умолчанию, используя значение по умолчанию ?attr/colorControlHighlight (которое вы также можете установить в своей теме, если хотите).

Примечание: вам нужно создать настраиваемый селектор меньше чем v21:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/primaryPressed" android:state_pressed="true"/>
    <item android:drawable="@color/primaryFocused" android:state_focused="true"/>
    <item android:drawable="@color/primary"/>
</selector>

Предполагая, что у вас есть несколько цветов, которые вы хотели бы использовать по умолчанию, нажатию и сфокусированному состоянию. Лично я сделал скриншот рябь на полпути, пока ее выбрали, и вытащил из нее основное/сфокусированное состояние.

Ответ 2

Существует еще одно простое решение для создания настраиваемого фона для кнопок "Плоские", сохраняя при этом их "материальные" эффекты.

  • Поместите свою кнопку в ViewGroup с нужным фоном.
  • установите selectableItemBackground из текущей темы в качестве фона для вашей кнопки (API >= 11)

то есть.

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/blue">
    <Button
        style="?android:attr/buttonStyleSmall"
        android:background="?android:attr/selectableItemBackground"
        android:textColor="@android:color/white"
        android:textAllCaps="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Button1"
        />
</FrameLayout>

Может использоваться для кнопок Flat, он работает с API >= 11, и вы получите эффект пульсации нa >= 21 устройствах, сохраняя регулярные кнопки на до 21, пока AppCompat не будет обновлен, чтобы поддерживать там пульсацию.

Вы также можете использовать selectableItemBackgroundBorderless только для кнопок = =.

Ответ 3

Вот простой и обратный совместимый способ доставки эффекта пульсации на поднятые кнопки с пользовательским фоном.

Ваш макет должен выглядеть следующим образом

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_custom_background"
    android:foreground="?android:attr/selectableItemBackground"/>

Ответ 4

Сегодня я столкнулся с этой проблемой, играя с библиотекой v22.

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

<style name="AppTheme" parent="BaseTheme">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>
    <item name="colorAccent">@color/accentColor</item>
    <item name="colorButtonNormal">@color/primaryColor</item>
</style>

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

Не забудьте добавить android: перед именами элементов в вашем стиле v21.

Ответ 5

С AppCompat (22.1.1+) вы можете добавить такой стиль:

<style name="MyGreenButton">
    <item name="colorButtonNormal">#009900</item>
</style>

И используйте его, просто применяя стиль:

<android.support.v7.widget.AppCompatButton
    style="@style/MyGreenButton"
    android:layout_width="match_width"
    android:layout_height="wrap_content"
    android:text="A Green Button"
    />

Программно изменяя цвет, я обнаружил, что единственным способом обновления цвета (на API 15 или 16) было использование "списка оттенков фона". И он не удаляет симпатичную радиальную анимацию на устройствах API 21:

ColorStateList colorStateList = new ColorStateList(new int[][] {{0}}, new int[] {0xFF009900}); // 0xAARRGGBB
button.setSupportBackgroundTintList(colorStateList);

Потому что button.setBackground(...) и button.getBackground().mutate().setColorFilter(...) не меняют цвет кнопки на API 15 и 16, как в API 21.

Ответ 6

Ответ @ianhanniballake абсолютно правильный и прост. Но мне потребовалось несколько дней, чтобы понять. Для тех, кто не понимает его ответа, вот более подробная реализация

<Button
        android:id="@+id/btn"
        style="@style/MaterialButton"
        ... />


<style name="MaterialButton" parent="Widget.AppCompat.Button.Colored">
    <item name="android:theme">@style/Theme.MaterialButton</item>
   ...
</style>


<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

=== Или ===

<Button
        android:id="@+id/btn"
        style="@style/Widget.AppCompat.Button.Colored"
        android:theme="@style/Theme.MaterialButton" />

<style name="Theme.MaterialButton" parent="YourTheme">
    <item name="colorAccent">@color/yourAccentColor</item>
    <item name="colorButtonNormal">@color/yourButtonNormalColor</item>
</style>

Ответ 7

Я использовал backgroundTint и передний план:

<Button
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:backgroundTint="@color/colorAccent"
    android:foreground="?android:attr/selectableItemBackground"
    android:textColor="@android:color/white"
    android:textSize="10sp"/>

Ответ 8

v22.1 of appcompat-v7 представил некоторые новые возможности. Теперь можно назначить конкретную тему только одному виду.

Устаревшее использование приложения: тема для стилизации панели инструментов. Теперь вы можете использовать android: тема для панелей инструментов на всех уровнях API 7 и выше и android: поддержка темы для всех виджетов на уровне API 11 и выше устройства.

Итак, вместо того, чтобы задавать нужный цвет в глобальной теме, мы создаем новую и назначаем ее только Button

Пример:

<style name="MyColorButton" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorButtonNormal">@color/myColor</item>
</style>

И используйте этот стиль в качестве темы вашего Button

<Button
 style="?android:attr/buttonStyleSmall"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Button1"
 android:theme="@style/MyColorButton"/>

Ответ 9

Используйте backgroundTint вместо background

Ответ 10

Я пришел в это сообщение, ища способ иметь цвет фона моего элемента ListView, но сохраняю пульсацию.

Я просто добавил свой цвет в качестве фона и selectableItemBackground в качестве переднего плана:

<style name="my_list_item">
    <item name="android:background">@color/white</item>
    <item name="android:foreground">?attr/selectableItemBackground</item>
    <item name="android:layout_height">@dimen/my_list_item_height</item>
</style>

и он работает как шарм. Я предполагаю, что тот же метод можно использовать и для кнопок. Удачи:)

Ответ 11

Если вам нравится использовать стороннюю библиотеку, посмотрите traex/RippleEffect. Это позволяет добавить эффект Ripple к представлению ЛЮБОЙ всего несколькими строками кода. Вам просто нужно обернуть в вашем файле макета xml элемент, который должен иметь эффект пульсации с контейнером com.andexert.library.RippleView.

В качестве дополнительного бонуса он требует Min SDK 9, поэтому вы можете иметь согласованность дизайна в версиях ОС.

Вот пример, взятый из репозитория GitHub библиотек:

<com.andexert.library.RippleView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:rv_centered="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@android:drawable/ic_menu_edit"
        android:background="@android:color/holo_blue_dark"/> 

</com.andexert.library.RippleView>

Вы можете изменить цвет пульсации, добавив этот атрибут в элемент RippleView: app:rv_color="@color/my_fancy_ripple_color

Ответ 12

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="#fff"
    android:textColor="#000"
    android:text="test"/>

Используйте

xmlns:app="http://schemas.android.com/apk/res-auto"

а цвет будет априт на pre-lolipop

Ответ 13

Если вы заинтересованы в ImageButton, вы можете попробовать эту простую вещь:

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/ic_button"
    android:background="?attr/selectableItemBackgroundBorderless"
/>

Ответ 14

В большом учебнике объясняются два подхода: Алекс Локвуд: http://www.androiddesignpatterns.com/2016/08/coloring-buttons-with-themeoverlays-background-tints.html:

Подход №1: изменение цвета фона кнопок с ThemeOverlay

<!-- res/values/themes.xml -->
<style name="RedButtonLightTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/googred500</item>
</style>

<Button
    style="@style/Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:theme="@style/RedButtonLightTheme"/>

Подход # 2: настройка фонового оттенка AppCompatButtons

<!-- res/color/btn_colored_background_tint.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Disabled state. -->
    <item android:state_enabled="false"
          android:color="?attr/colorButtonNormal"
          android:alpha="?android:attr/disabledAlpha"/>

    <!-- Enabled state. -->
    <item android:color="?attr/colorAccent"/>

</selector>

<android.support.v7.widget.AppCompatButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:backgroundTint="@color/btn_colored_background_tint"/>

Ответ 15

Я пробовал это:

android:backgroundTint:"@color/mycolor"

вместо изменения свойства фона. Это не снимает материальный эффект.