Добавить эффект ряби к моей кнопке с цветом фона кнопки?

128

Я создал кнопку и хочу добавить к ней эффект ряби!

Я создал XML-файл кнопки bg: (bg_btn.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>

И это мой файл с эффектом пульсации: (ripple_bg.xml)

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

А это моя кнопка, которой я хочу добавить эффект пульсации:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="@drawable/ripple_bg"
android:clickable="true" />

Но после добавления эффекта пульсации фон кнопки становится прозрачным, и кнопка отображается только при нажатии, например:

Перед нажатием

По щелчку

Но мне нужны как цвет фона кнопки, так и эффект пульсации, я нашел часть этого кода в разных блогах Stack Overflow, но все равно он не работает!

rakcode
источник
пожалуйста, сделайте скриншоты намного меньше в следующий раз .. (измените размер перед загрузкой)
user25
@ user25, вы также можете просто добавить lили mк ссылке на изображение. (см. мою правку)
Suragch

Ответы:

157

Вот еще один доступный XML для тех, кто хочет добавить все вместе градиентный фон, радиус угла и эффект ряби:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorPrimaryLight"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>
</ripple>

Добавьте это к фону вашей кнопки.

<Button
    ...
    android:background="@drawable/button_background" />

PS: этот ответ работает для android api 21 и выше.

Пей
источник
4
@pei Как вы, ребята, получили эту информацию? Я имею в виду, откуда вы знаете, что для этой работы есть XML-элемент под названием ripple?
1
Это одна из концепций, используемых в материальном дизайне. Начните вводить новый корневой тег в XML-формате с возможностью рисования в Android Studio, тогда вы сможете увидеть все доступные теги, включая ripple.
Пей
1
Какая польза от предмета маски?
Prashant
10
для этого требуется уровень API 21
M.kazem Akhgary
2
он работает, но не объясняется, как это работает. он должен быть связан с идентификатором элемента. Следует упомянуть.
oiyio
157

Добавьте "?attr/selectableItemBackground"к android:foregroundатрибуту вашего представления, если он уже имеет фон вместе с android:clickable="true".

backslashN
источник
не всегда работает, но вы можете добавить фон к эффекту пульсации, как указано в комментариях к принятому ответу
Тайлер
Мне пришлось использовать это решение, поскольку я использовал собственный фон для своей кнопки. Это сработало отлично.
bnayagrawal
@ROAR, верно, но по крайней мере: «Это не ошибка; приложение просто проигнорирует атрибут. Однако, если атрибут важен для внешнего вида или функциональности вашего приложения, вам следует подумать о поиске альтернативного способа достижения тот же результат только с доступными атрибутами, а затем вы можете дополнительно создать копию макета в папке layout-vNN, которая будет использоваться в API NN или выше, где вы можете воспользоваться преимуществами нового атрибута. " Таким образом, он хорошо работает на устройствах с более высоким API 23 и игнорируется, когда находится ниже (мы можем просто tools:ignore="UnusedAttribute).
JorgeAmVF
без библиотеки поддержки Android это было бы ?android:attr/selectableItemBackground( android:attrвместо attr)
Выходные,
1
android:foregroundатрибут не влияет на уровни API ниже 23
Вадим Котов
68

Добавление эффекта ряби / анимации к кнопке Android

Просто замените атрибут фона кнопки на android: background = "? Attr / selectableItemBackground", и ваш код будет выглядеть так.

      <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/selectableItemBackground"
        android:text="New Button" />

Еще один способ добавить эффект ряби / анимацию к кнопке Android

Используя этот метод, вы можете настроить цвет эффекта ряби. Во-первых, вам необходимо создать XML-файл в каталоге доступных для рисования ресурсов. Создайте файл ripple_effect.xml и добавьте следующий код. Рез / рисуем / ripple_effect.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

И установите фон кнопки на указанный выше файл ресурсов.

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_effect"
    android:padding="16dp"
    android:text="New Button" />
Джигар Патель
источник
1
Для меня эффекта ряби не возникло. это был просто переключатель цвета для кнопки: / Моя версия Android 5.1.1, так что она должна работать. Не могли бы вы помочь? Я пошел по твоим стопам
UrviG 05
android: color должен отличаться от мачты android: color, иначе вы хотите увидеть эффект ряби
SpyZip
2
если вам нужен фон, вы просто добавляете еще один элемент к ряби, например: <item android: drawable = "? attr / colorPrimary" />
Тайлер
36

В дополнение к решению Jigar Patel добавьте его в ripple.xml, чтобы избежать прозрачного фона кнопок.

<item
    android:id="@android:id/background"
    android:drawable="@color/your-color" />

Полный xml :

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/your-color"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/your-color" />
        </shape>
    </item>
    <item
        android:id="@android:id/background"
        android:drawable="@color/your-color" />
</ripple>

Используйте этот ripple.xml в качестве фона для вашей кнопки:

android:background="@drawable/ripple"
Судиш Р
источник
2
Нам не нужно было использовать <item android:id="@android:id/mask"> [...]. Если только вам не нужна овальная маска. Спасибо за Ваш ответ!
Filipe Brito
В любом случае, что делает этот <item android: id = "@ android: id / mask">, я создал 2 похожих элемента с этим атрибутом и без него, и они выглядят совершенно одинаково
Сартерис Штормхаммер
@SartherisStormhammer из официальных документов: если установлен слой маски, эффект ряби будет замаскирован против этого слоя, прежде чем он будет нарисован поверх композиции остальных дочерних слоев. Если слой маски не задан, эффект пульсации маскируется по составу дочерних слоев. Это ссылка, developer.android.com/reference/android/graphics/drawable/…
Sudheesh R
@SudheeshR, что еще больше сбивает с толку
Сартерис Штормхаммер,
@SartherisStormhammer Из той официальной документации Я думаю, это довольно ясно. Эффект ряби будет рисовать на дочерних / замаскированных слоях. Пожалуйста, прочтите документ еще раз, вы поймете суть.
Sudheesh R
33

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

    <Button
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:gravity="center"
    android:layout_centerHorizontal="true"                                                             
    android:background="@drawable/shape_login_button"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:text="@string/action_button_login"
     />

Добавьте ниже параметр для эффекта пульсации

   android:foreground="?attr/selectableItemBackgroundBorderless"
   android:clickable="true"

Для справки см. Ссылку ниже https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/

Жасмин Джон
источник
2
Атрибут android: передний план не влияет на уровни API ниже 23
Али Хаки
1
Одним из недостатков этого подхода является то, что хотя фон моей кнопки был овальным, рябь распространялась до прямоугольных краев.
iCantC
15

AppCompat v7 +

Если вы не укажете префикс, ?android:ваше приложение выйдет из строя.

Вы должны использовать "?android:attr/selectableItemBackground"или "?android:attr/selectableItemBackgroundBorderless", в зависимости от ваших предпочтений. Я предпочитаю Borderless.

Вы можете поместить его android:backgroundили android:foregroundоставить существующие свойства.

Чтобы это работало, элемент должен иметь android:clickable="true"и android:focusable="true", но многие элементы, такие как кнопки, имеют их trueпо умолчанию.

<Button
    ...
    android:background="@color/white"
    android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
    ...
    android:background="?android:attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:focusable="true"
/>

Программно (Java)

TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type

Программно (Котлин)

val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type

Многоразовая функция расширения Kotlin

myView.ripple()

fun View.ripple(): View {
    val value = TypedValue()
    context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
    setBackgroundResource(value.resourceId)
    isFocusable = true // Required for some view types
    return this
}
Gibolt
источник
7

У меня сработало добавление атрибутов переднего плана и интерактивных атрибутов.

<Button
    ... 
    android:background="@color/your_color"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true" />
Ashwin
источник
6

В дополнение к Sudheesh R

Добавление эффекта ряби / анимации к кнопке Android с прямоугольной формой кнопки с углом

Создайте XML-файл res / drawable / your_file_name.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/colorWhite"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="50dp" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorAccent"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="50dp" />
        </shape>
    </item>
</ripple>
Дигвиджай Мачале
источник
4

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

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

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

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

Вы можете использовать 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 (которое вы также можете установить в своей теме, если хотите).

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

<?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>
Атман Бхатт
источник
Я использую minSDK lvl 21
rakcode
нет папки с возможностью переноса v21, только одна папка, которая сама папка
v21
да, я тоже использовал этот API, если я использую этот API после щелчка, мое приложение
вылетает
на самом деле, я тестирую свое приложение на своем телефоне в режиме отладки, а моя ОС - CyanogenMod13 (Android 6, Marshmellow)
rakcode
4

попробуй это

<Button
            android:id="@+id/btn_location"
            android:layout_width="121dp"
            android:layout_height="38dp"
            android:layout_gravity="center"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:foreground="?attr/selectableItemBackgroundBorderless"
            android:clickable="true"
            android:background="@drawable/btn_corner"
            android:gravity="center_vertical|center_horizontal"
            android:paddingLeft="13dp"
            android:paddingRight="13dp"
            android:text="Save"
            android:textColor="@color/color_white" />
Raveendra
источник
4

Простой подход - установить тему представления, как описано здесь .

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>
Адам Гурвиц
источник
3

Просто используйте:

android:backgroundTint="#f816a463"

Вместо того:

android:background="#f816a463"

Не забудьте изменить свой Buttonнаandroid.support.v7.widget.AppCompatButton

Гилад Шапира
источник
1
Плохо то, что если вам нужна кнопка, чтобы заполнить 100% горизонтальный экран, вы этого не сделаете.
Filipe Brito
1

Альтернативное решение для использования <ripple> тега (которое я лично предпочитаю не делать, потому что цвета не являются "стандартными") следующее:

Создайте объект для рисования для фона кнопки и включите его <item android:drawable="?attr/selectableItemBackground">в<layer-list>

Затем (и я думаю, что это важная часть) программно устанавливается backgroundResource(R.drawable.custom_button)на вашем экземпляре кнопки.

Деятельность / Фрагмент

Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);

раскладка

<Button
    android:id="@+id/btn_temp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_button"
    android:text="Test" />

custom_button.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground" />
</layer-list>
Эйдан Хост
источник
Зачем снова программно устанавливать backgroundResource, в то время как макет xml определяет фон кнопки?
SunnyShiny9