Ripple эффект android что это

Создаем кнопку с 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 :

Подобное использование кнопки будет вести себя как ожидается:

Читайте также:  Palit geforce gtx 1080 gamerock premium майнинг

Далее добавим стили кнопки и возможность прописывать кастомный (вдруг кому-то понадобится) класс. Для этих целей отлично подойдет 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 , иначе можно получить массив со старыми значениями, и все будет работать не так как задумано.

Полный код кнопки:

Итоговый результат можно поклацать здесь

Заключение

Достаточно много было опущено, например как настроен проект, как пишется документация, тесты под новый компонент в проекте. Я постараюсь покрыть эти темы отдельными публикациями.

Источник

Android L’Ripple Effect – Touch Feedback для кнопок – использование XML

Я пытаюсь понять, как реализовать «Ripple Effect – Touch Feedback» для кнопок и других видов. Я посмотрел на вопросы, связанные с эффектом касания Ripple на SO и получил некоторое представление об этом. Я смог успешно получить эффект пульсации, используя этот Java-код.

Читайте также:  Куда семья может инвестировать

Но я хочу использовать XML-подход. Как мне это достичь? Я посмотрел на это и на это , но я еще не настолько комфортно со стилями, поэтому мне трудно добиться эффекта пульсации.

У меня есть кнопка со следующим кодом XML:

Как получить эффект пульсации для этой кнопки. Если кто-то может вести меня, я буду благодарен.

[EDIT] Добавление ripple.xml и background.xml, как указано в одной из приведенных выше ссылок. Я создал папку drawable-v21 в res и добавил туда файлы ниже.

Я добавил рябь в качестве фона для моей кнопки, вот xml для моей кнопки сейчас.

Когда я запускаю приложение, я получаю исключение ResourceNotFoundException. Вот трассировка logcat.

Вы можете сделать что-то вроде этого:

Больше информации здесь .

Просто поместите ?attr/selectableItemBackground на фоне кнопки для API 21+, как показано ниже:

Для lollipop (API> 21) сделайте файл как btn_ripple_effect.xml в drawable и поставьте ниже код

Для pre lollipop (API

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

Вы можете делать более сложные вещи с пульсацией. Например, если вам нужна рамка на кнопке пульсации, вы можете использовать ее как список слоев.

Обратите внимание, что элемент с id @android:id/mask используется только для отображения, где эффект пульсации будет остановлен. Если вы хотите, чтобы он охватывал всю кнопку, вы можете изменить android:shape как rectangle . Вы можете представить себе и другие интересные вещи с этим!

Также убедитесь, что резервная копия предназначена для устройств, которые еще не 21, или приложение будет аварийно завершено на старых устройствах.

Лучший способ использовать это в android: foreground , потому что он позволяет также использовать собственный фон.

Android: передний план = «андроид: атр / selectableItemBackground»

Я изучал эффект пульсации, так как это было то, что я хотел применить к нескольким кнопкам в своем приложении и произошло на вашем посту. В то время как ваш вопрос ищет ответ о том, как добавить эффект пульсации с помощью XML, на самом деле я пытался избежать этого, поскольку при попытке добавить этот атрибут вы видите, что ему требуется v21.

Если вы ориентируетесь ниже, чем v21, чем этот новый класс, расширяющий Button (или ImageButton и т. Д.), Будет избегать жалоб от компилятора.

Поскольку не было объяснений о том, как реализовать пользовательский класс выше, я думал, что заполнил бы. Все, что вам нужно сделать, это создать новый класс, а затем в XML-изменении «Button» на «the.package.name.MyButton».

Вот и все. Теперь ваша кнопка при нажатии будет иметь пульсацию, содержащуюся в пределах ее границ.

Мне нравится этот подход, я просто хочу, чтобы рябь распространилась по границам. Для маленькой кнопки этот эффект пульсации действительно подчеркивает, насколько квадратная или прямоугольная кнопка на самом деле. Визуально было бы более удовлетворительно, если бы пульсация продолжалась до тех пор, пока она не достигнет своего полного радиуса.

Вы можете добавить clickable как true и background или foreround как foreround ?attr/selectableItemBackground foreround для представления:

Если в случае, если в вашем представлении уже есть background заполненный чем-то, вы можете заполнить свой foreground selectableItemBackground

Источник

Оцените статью