- Android, setting background color of button loses ripple effect
- 7 Answers 7
- Add ripple effect to my button with button background color?
- 14 Answers 14
- AppCompat v7+
- Programmatically (Java)
- Programmatically (Kotlin)
- Reusable Kotlin Extension Function
- A simple approach is to set a view theme as outlined here.
- How to make a circular ripple on a button when it’s being clicked?
- Background
- The problem
- The question
- 12 Answers 12
- Just Add this background to your view
- Создаем кнопку с Ripple Effect для XMars UI
- Введение
- The Button
- HTML / CSS
- React компонент
- Ripple Effect
- Заключение
Android, setting background color of button loses ripple effect
After adding color to an android button, it loses its ripple effect that makes the user feel like there is a responsive click. How do I fix this? I’ve searched through many solutions but I couldn’t find a definite one that wasn’t ambiguous.
7 Answers 7
You can add the ripple effect & background color with an additionnal ripple drawable:
ripple.xml (this is where you can add background color in addition to the ripple effect) :
A very simple and straight forward way of doing this is to set ?attr/selectableItemBackground to android:foreground attribute of your button. Following xml is perfectly valid and works
Don’t change the background of Button. Change the theme.
and in your xml file
Or you can add it in your main app theme
And don’t need change button background.
If you want totally custom background you need create your selector. And you can set there ripple effect.
Don’t forget to change your Button to android.support.v7.widget.AppCompatButton
There was no answer for MaterialButton, so i will put it here.
For MaterialButton (com.google.android.material.button.MaterialButton), use ‘backgroundTint’ and ‘rippleColor’.
?attr/colorControlHighlight is the default ripple color, you can change this value.
Actually, you can use of drawables to combine ripple effect with any other drawable. This is a universal solution also for pre-lolipop: I’ve tested it in many configurations.
The only problem is that pre-lolipop crashes when ?selectableItemBackground appears inside , so we have to create LayerDrawable programmatically.
A very fast simple solution looks like:
Specify for your View
Then anywhere in the code create mySpecialDrawable and do the trick:
Please note that .mutate() for LayeredDrawable is essential here!
A more complex solution could be useful when you already have your custom View and prefer rather extend its functionality and compatibility than add extra empty FrameLayout as a parent.
Inside attrs.xml put:
then inside your View-descendant class:
I prefer this approach because it has no issues like android:foreground attribute which is 23+ or extra overhead of enclosing clickable views inside FrameLayout.
Источник
Add ripple effect to my button with button background color?
I created a button and I want to add ripple effect to that button!
I created a button bg XML file: (bg_btn.xml)
And this is my ripple effect file: (ripple_bg.xml)
And This is my Button which I want to add ripple effect:
But after adding ripple effect button background is transparent, and button display only when clicked, like this:
But I need both button background color and ripple effect, I found some of this code in different blogs of Stack Overflow, but still it is not working!
14 Answers 14
Here is another drawable xml for those who want to add all together gradient background, corner radius and ripple effect:
Add this to the background of your button.
PS: this answer works for android api 21 and above.
Add the «?attr/selectableItemBackground» to your view’s android:foreground attribute if it already has a background along with android:clickable=»true» .
Add Ripple Effect/Animation to a Android Button
Just replace your button background attribute with android:background=»?attr/selectableItemBackground» and your code looks like this.
Another Way to Add Ripple Effect/Animation to an Android Button
Using this method, you can customize ripple effect color. First, you have to create a xml file in your drawable resource directory. Create a ripple_effect.xml file and add following code. res/drawable/ripple_effect.xml
And set background of button to above drawable resource file
In addition to Jigar Patel‘s solution, add this to the ripple.xml to avoid transparent background of buttons.
Complete xml :
Use this ripple.xml as background in your button :
When the button has a background from the drawable, we can add ripple effect to the foreground parameter.. Check below code its working for my button with a different background
Add below parameter for the ripple effect
AppCompat v7+
If you don’t prefix with ?android: your app will crash.
You should use «?android:attr/selectableItemBackground» or «?android:attr/selectableItemBackgroundBorderless» , based on your preference. I prefer Borderless .
You can put it either in android:background or android:foreground to keep existing properties.
The element must have android:clickable=»true» and android:focusable=»true» in order for this to work, but many elements, such as buttons, have them true by default.
Programmatically (Java)
Programmatically (Kotlin)
Reusable Kotlin Extension Function
In addition to Sudheesh R
Add Ripple Effect/Animation to a Android Button with button rectangle shape with corner
Create xml file res/drawable/your_file_name.xml
Adding foreground and clickable attributes worked for me.
A simple approach is to set a view theme as outlined here.
When you use android:background, you are replacing much of the styling and look and feel of a button with a blank color.
Update: As of the version 23.0.0 release of AppCompat, there is a new Widget.AppCompat.Button.A colored style which uses your theme’s colorButtonNormal for the disabled color and colorAccent for the enabled color.
This allows you apply it to your button directly via
You can use a drawable in your v21 directory for your background such as:
This will ensure your background color is ?attr/colorPrimary and has the default ripple animation using the default ?attr/colorControlHighlight (which you can also set in your theme if you’d like).
Note: you’ll have to create a custom selector for less than v21:
Источник
How to make a circular ripple on a button when it’s being clicked?
Background
On the dialer app of Android, when you start searching for something, and you click the arrow button on the left of the EditText, you get a circular ripple effect on it :
The problem
I’ve tried to have it too, but I got a rectangular one:
The question
How do I make the button have a circular ripple effect when being clicked? Do I have to create a new drawable, or is there a built in way for that?
12 Answers 12
If you already have a background image, here is an example of a ripple that looks close to selectableItemBackgroundBorderless:
state_pressed_ripple.xml: (opacity set to 10% on white background) 1AFFFFFF
If you are using AppCompat theme, then you could set the background of the view as:
This will add circular ripple on 21 and above and square background on below 21.
Another attribute with round ripple effect, specially for action bar:
UPD: Ripple color can be changed by this attribute:
But keep in mind, this attribute applies to all default ripple effects.
Create and set a ripple drawable as background. Something like this.
Just Add this background to your view
You can create circle ripple drawable using android:radius attribute in xml.
Pay attention, that your your_radius should be less then your view width and height. For example: if you have view with size 60dp x 60dp your_radius should be near 30dp (width / 2 or height / 2).
just add this item in your activity xml
If you want more generic XML files, I have two files:
1) btn_ripple_background with code:
2) ripple_circuler_shape with code:
finally the usage: android:foreground=»@drawable/ripple_btn_background»
Источник
Создаем кнопку с Ripple Effect для XMars UI
Всем привет, сегодня я расскажу вам как разрабатывал кнопку для XMars UI проекта. О да, вроде мелочь, но есть о чем рассказать. Я опущу детали которые связаны с добавлением нового компонента в опенсорс проект. Более детально я расскажу про проект в отдельной статье.
Введение
XMars UI — это один из моих новых опенсорс проектов. Простая библиотека UI компонентов под HTML / CSS и React. В будущем планирую поддерживать Vue. Пока в ней только кнопка и иконки 🙂
Проект родился как идея в рамках Telegram Contest, cуть которого заключалась в разработке веб версии клиента. Вместе с коллегой мы решили, а почему бы и не принять в этом участие. Роли поделились так, что на мне верстка, а когда коллега разберется с авторизацией, то я подключусь писать компоненты. Все бы хорошо, но авторизоваться в Телеграмме не так просто. В итоге мы нечего не отправили, а я наверстал кучу всего и выходит — зря. Но как говорит Варламов, ваш проект уже чего-то стоит, раз вы потратили на него свое время. С этим сложно не согласится, ведь если переводить на часы и денежки, то только настройка Webpack в самом начале проекта уже не бесплатно. Смотря на все это безобразия, решил надо как-то выкинуть на опенсорс. Что один бутстрап использовать? Хочется свой UI фреймворк под другие свои проекты.
The Button
Кнопка в интерфейсе — пожалуй главный элемент с помощью которого пользователь взаимодействует с приложением. Следовательно, это один из первых компонентов любого UI фреймворка / библиотеки.
В дизайне Телеграм, не так много вариаций кнопок:
Я выделил 3 основных (default, accent, primary), круглую с иконкой и зеленую. Есть еще полу прозрачная, но опустим ее. По большей части разрабатывая XMars UI я стараюсь исходить из потребностей, не придумал куда бы понадобилась прозрачная кнопка.
Пользователю библиотеки должно быть удобно использовать CSS классы. Я не фанат таких систем нейминга как БЭМ. Мне больше нравится, то как Bootstrap задает имена классам. Но я бы упростил еще немного. Вместо .btn .btn-primary — просто .btn .primary . А в случае с React компонентом, будет выглядеть так:
Такая же кнопка но ripple effect:
HTML / CSS
UI библиотека не должна быть привязана к какому-либо UI фреймворку. В будущем планирую натянуть верстку и на Vue компоненты. По этому начнем с простого HTML / CSS.
Под капотом у проекта Tailwindcss, это utility-first CSS framework, то есть фреймворк который предоставляет вам утилиты, вместо полноценных компонентов.
Помимо Tailwindcss, используется PostCSS для миксинов, переменных и вложенных стилей
Более детально об использовании такого фреймворка и как настроен проект, я расскажу в отдельной статье. На данным этапе достаточно того, что у нас есть такой мощный инструментарий и для создания компонентов он используется по полной.
Тег имеет ряд дефолтных стилей которые нам необходимо либо убрать, либо переопределить.
В случае с Tailwindcss, тег кнопки имеет такой стиль:
Все лишнее по умолчанию убрано. Можно лепить, что хочешь не боясь, что на каком-то состоянии выпадет дефолтный бордер. Но тут же оговорочка, дефолтный outline все таки нужно прибить:
Кнопка в XMars UI имеет класс .btn :
Добавляем этот класс в наши стили:
Помимо того, что Tailwindcss предоставляет классы которые вы можете использовать, он предоставляет своего рода mixins . @apply это не SCSS или какой-то плагин под PostCSS. Это синтаксис самого Tailwindcss. Стили, которые применяются в целом семантически понятны из названия. Единственно py-3 и px-4 могут вызывать вопросы. Первый это padding по y, то есть по вертикали, а именно — padding-top: 0.75rem; padding-bottom: 0.75rem; . Следовательно, px-4 по горизонтали — padding-right: 1rem; , padding-left: 1rem; .
Дизайн, который предоставил Телегерамм мягко говоря плохо задокументирован и такие вещи как border-radius кнопки приходится брать линейкой прямо из изображения. Когда нибудь задумывались, что именно означанют значения в border-radius ?
Это буквально радиус получаемого круга в угле. Если по колхозу, то можно изменить линейкой как показано на картинке выше. Так я и сделал используя прямоугольное выделение в Gimp.
border-radius у кнопок в дизайне равен 10px, к сожалению такого класса из коробки в Tailwindcss нет, но мне визуально хватило rounded-lg который равен 8px при дефолтном размере шрифта (rem).
Вот что получилось на данный момент, я закрасил кнопку в серый, что бы было видно края:
Далее нам необходимо сделать эффект на :hover . Тут дизайнеры из Телеграмм решили пролить немного света и указали цвет как 0.08% от #707579 . Я вижу два варианта, просто взять цвет пипеткой или же сделать как задокументировано. Первый вариант проще, но на прспективу не самый хороший. Дело в том, что если задний фон будет отличаться от белого, то на :hover мы будем получать конкретный цвет, терять «легкость» и прозрачность кнопки. По этому лучше последовать документации и заложить альфа самца канал. Сделать это можно бесчисленным количеством способов, например использовать SCSS функции по работе с цветом. Но в проекте нет SCSS, а из за одного цвета подключать какой-то плагин к PostCSS не хочется, сделаем все очень просто. В Chrome, есть колопикер который позволяет трансформировать цвета в разные системы, вбиваем туда HEX цвета #707579 , переводим в rgba и задаем альфа канал — 0.08%.
Вуаля! Что-то у меня резко флешбэчнула картинка:
Получаем — rgba(112, 117, 121, 0.08) .
(:hover)
Далее скучно и без особых усилий, я добавил остальные состояния:
React компонент
Изначально, кнопка версталась под контест Телеграмма и использовать какой-либо фреймворк было нельзя. Пришлось, реализовал ripple effect на чистом JS. Мне бы очень хотелось, что бы так и осталось, но пока проектом занимаешься в одиночку, приходится чем-то жертвовать.
Компоненты, которые требуют какой-либо логики, например такой, как ripple effect, будут реализованы и доступны только в виде React компонентов.
Завернуть кнопку в React компонент особого труда не составляет:
Данная кнопка будет отображаться в заданном стиле, но по факту от нее толку мало. Нам необходимо дать возможность пользователю кастомизировать кнопку, добавлять собственные стили, навешивать обработчики события и так далее.
Для того, что бы пользователь мог передать все необходимое, для начала нужно побороть Typescript, иначе даже onClick не даст нормально передать. Немного подредактировав интерфейс ButtonProps , решаем проблему:
после чего мы можем смело делать деструкцию props :
Подобное использование кнопки будет вести себя как ожидается:
Далее добавим стили кнопки и возможность прописывать кастомный (вдруг кому-то понадобится) класс. Для этих целей отлично подойдет npm пакет classnames.
Класс btn устанавливается всегда, а вот primary и accent только если равны true . Classnames добавляет класс, если в значении у него логическое true , используя сокращение из ES6 получается простая запись < primary >, вместо < primary: true >.
additionalClass — строка, и если она будет пустая или undefined, для нас особой роли не играет, просто к элементу нечего не добавится.
По началу я присваивал props следующим образом:
Опуская, все, что не относится к props элемента кнопки, но в этом нет необходимости так как React не отренедрит лишнее.
Ripple Effect
Собственно так это и выглядит, но желательно, что бы «волна» расходилась от места клика.
Способов сделать такую анимацию бесчисленное количество, это как шутка про синий квадрат.
Но погуглив, посмотрев примеры на codepen, стало понятно, что в большинстве случаев, реализуется «волна» через дочерний элемент, который расширяется и пропадает.
Позиционируется он внутри кнопки по координатам клика. В XMars UI на данный момент я решил не реализовать данный эффект на onPress как это делает Material UI, но в будущем планирую доработать. Пока только на onClick .
На картинке выше вся магия. На клик создается дочерний элемент кнопки, позиционируется абсолютно, по центру клика и расширяется. Свойство overflow: hidden , не дает «волне» выйти за пределы кнопки. Элемент необходимо удалить по окончанию анимации.
Сначала определим стили, где можно, по максимуму используем Tailwindcss:
Элементу отвечающему за эффект будет присвоен класс .ripple . border-radius: 50%; равняется кругу (по 50% скругления на угол * 2), у кнопки позиционирование относительное, у .ripple — абсолютное кнопке. Анимация очень простая, «волна» увеличиваясь становится прозрачной за 0.6 секунды. Цвет фона такой же как :hover и складываясь, два прозрачных цвета «волны» и кнопки дают нам желаемый результат. На синей .primary кнопке это уже не так принципиально и там можно использовать не прозрачный цвет.
На клик необходимо создавать элемент «волны». Поэтому создаем под это дело стейт и добавляем кнопке соответствующий обработчик клика, но таким образом, что бы он не мешал пользовательскому onClick.
rippleElements — массив JSX элементов, функция рендера тут может показаться излишней, но это больше дело стиля и заделки на будущее.
onRippleClick обработчик которыый создает «волны». По клику на кнопке, мы узнаем размеры кнопки, которые используются для правильного позиционирования круга, после чего все необходимое передается в функцию newRippleElement которая в свою очередь просто создает div элемент с классом ripple , здавая необходимые стили для позиционирования.
Из главных вещей стоит выделить onAnimationEnd . Данный ивент нам необходим для отчистки DOM от уже отработавших элементов.
Очень важно не забыть, передать в аргументы текущие rippleElements , иначе можно получить массив со старыми значениями, и все будет работать не так как задумано.
Полный код кнопки:
Итоговый результат можно поклацать здесь
Заключение
Достаточно много было опущено, например как настроен проект, как пишется документация, тесты под новый компонент в проекте. Я постараюсь покрыть эти темы отдельными публикациями.
Источник