TAO Bubbles: элегантные и настраиваемые подсказки для ваших Jetpack Compose приложений

от автора

Каждый Android-разработчик сталкивается с задачей обучения пользователей новым функциям или помощи в навигации по интерфейсу. Традиционные всплывающие окна или сообщения могут быть навязчивыми. Конечно же есть способ элегантно подсвечивать элементы UI и предоставлять контекстную помощь. Встречайте TAO Bubbles – легковесную библиотеку для Jetpack Compose, созданную для отображения настраиваемых «пузырей«, «подсказок» или «тултипов«, которые могут указывать на конкретные UI-компоненты.TAO Bubbles прекрасно подходит для создания пошаговых руководств, демонстрации новых возможностей или предоставления контекстно-зависимой справки прямо в вашем приложении.

P.S. Проект создавался во время изучения Jetpack Compose, так что конструктивная критика и pull requests с улучшениями приветствуется ).

Ключевые особенности TAO Bubbles для Jetpack Compose

  • Полная кастомизация внешнего вида: Управляйте положением стрелки, размером, радиусом углов, цветами, границами и многим другим. Вы можете легко адаптировать стиль подсказок под дизайн вашего приложения. Внутри можно расположить любой ваш макет Composable.

  • Гибкое позиционирование: Подсказки могут указывать на любую сторону целевого composable-компонента (LEFT, RIGHT, TOP, BOTTOM).

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

  • Последовательный показ: Используйте BubbleShowController для легкого отображения серии подсказок одна за другой, проводя пользователя через несколько шагов.

  • Анимации появления/исчезновения: Плавные и настраиваемые анимации для появления и исчезновения подсказок делают взаимодействие более живым.

  • Затемнение фона (Scrim): Опциональный слой затемнения фона помогает сфокусировать внимание пользователя на подсказке.

  • Декларативный API: Библиотека разработана с учетом современных практик Jetpack Compose, предлагая простой и интуитивно понятный API.

  • Легкое использование: Никаких сложных конструкций. Добавление к существующему проекту очень простое.

Как это работает?

Пример использования (одиночный Bubble):

Определяете общие стили для всех ваших «пузырей» или для конкретной группы.

    val settings = BubblesSettings(             scrimColor = Color(0x22002EFF), // Цвет затемнения фона             backgroundColor = OrangeVeryLight, // Цвет фона подсказки             bubbleBorderColor = Color.Black, // Цвет рамки             bubbleBorderWidth = 2.dp // Толщина рамки             ... и так далее         )

Подготавливаете данные для каждой подсказки.

    val bubbleData = BubbleData(         id = "Intro_Feature", // Уникальный ID для сохранения состояния (показана/скрыта)         arrowPosition = ArrowPosition.BOTTOM, // С какой стороны целевого объекта прилегает стрелка и подсказка         content = { onDismissClick, onStopShowRequest ->             // Здесь размещается любой ваш Composable-контент для подсказки             // onDismissClick - функция вызываемая по закрытию подсказки             // onStopShowRequest - функция для остановки всей последовательности (если используется BubbleShowController)             Text("Это важная новая кнопка!")         }     )

И используете эти данные в своем коде:

    @Composable     fun SingleBubbleExample() {         var showBubble by remember { mutableStateOf(true) }         var targetRect by remember { mutableStateOf<Rect?>(null) } // Rect целевого компонента          Box(modifier = Modifier.fillMaxSize()) {             Button(                 onClick = { showBubble = !showBubble },                 modifier = Modifier                     .align(Alignment.Center)                     .onGloballyPositioned { coordinates ->                         // Получаем геометрию компонента, к которому будет привязана подсказка                         targetRect = coordinates.boundsInWindow()                     }             ) {                 Text("Показать подсказку")             }              Bubble(                 targetComponentRect = targetRect, // Передаем Rect цели                 bubbleData = bubbleData,          // Наши данные для подсказки                 settings = settings,              // Наши настройки стиля                 isVisible = showBubble,           // Управляем видимостью                 onDismissRequest = { showBubble = false } // Действие при закрытии             )                    }     }     

Настройка показа последовательных подсказок.
Показ большого количества подсказок не сильно сложнее. Для настройки используем BubbleShowController.

Подготавливаем список (или по одному) BubbleData для каждой подсказки:

    val testBubbles = listOf(         BubbleData(             id = "Step_1",             arrowPosition = ArrowPosition.BOTTOM,             content = { onDismissClick, onStopShowRequest ->                 MyContent("Подсказка 1: Нажмите здесь", onDismissClick, onStopShowRequest)             }         ),         BubbleData(             id = "Step_2",             arrowPosition = ArrowPosition.LEFT,             content = { onDismissClick, onStopShowRequest ->                 MyContent("Подсказка 2: Затем проверьте это", onDismissClick, onStopShowRequest)             }         ),         BubbleData(             id = "Step_3",             arrowPosition = ArrowPosition.RIGHT,             content = { onDismissClick, onStopShowRequest ->                 MyContent("Подсказка 3: И наконец, сюда!", onDismissClick, onStopShowRequest)             }         )     )      // MyContent - ваш кастомный Composable для содержимого подсказки     @Composable     fun MyContent(text: String, onDismiss: () -> Unit, onStopShow: () -> Unit) {         Column(horizontalAlignment = Alignment.CenterHorizontally) {             Text(text)             Button(onClick = onDismiss) { Text("Далее") }             // Button(onClick = onStopShow) { Text("Завершить тур") } // Если нужно         }     }     

И используем подготовленные данные в основном коде связывая каждый BubbleData с целевым объектом :

    @Composable     fun BubbleSequenceExample() {         // Подготовка показа         val bubblesSettings = remember { testSettings } // Используем ранее созданные настройки         val bubblesData = remember { testBubbles } // Используем ранее созданные данные для каждой подсказки. Но можно и по одному.          val bubbleShowController = rememberBubbleShowController( // Контроллер показа              settings = bubblesSettings,             bubbles = bubblesData,             onFinished = {                 // Действия после завершения всех подсказок                 Log.d("BubbleShow", "Все подсказки показаны!")             }         )          Box(             modifier = Modifier                 .fillMaxSize()                 .background(Color(0xFFE0F7FA))         ) {             // Ваши UI компоненты, к которым будут привязаны подсказки             Box(                 modifier = Modifier                     .align(Alignment.TopStart)                     .padding(16.dp)                     .size(100.dp)                     // Связываем компонент с данными подсказки через контроллер                     .assignBubble(controller = bubbleShowController, bubbleData = bubblesData[0]),                 contentAlignment = Alignment.Center             ) {                 Text("Элемент 1", color = Color.Black)             }              Box(                 modifier = Modifier                     .align(Alignment.TopEnd)                     .padding(16.dp)                     .size(100.dp)                     .assignBubble(controller = bubbleShowController, bubbleData = bubblesData[1]),                 contentAlignment = Alignment.Center             ) {                 Text("Элемент 2", color = Color.Black)             }              Box(                 modifier = Modifier                     .align(Alignment.BottomStart)                     .padding(16.dp)                     .size(100.dp)                     .assignBubble(controller = bubbleShowController, bubbleData = bubblesData[2]),                 contentAlignment = Alignment.Center             ) {                 Text("Элемент 3", color = Color.Black)             }              // Кнопка для перезапуска показа             Button(                 modifier = Modifier                     .align(Alignment.Center)                     .padding(top = 224.dp),                 onClick = {                     bubbleShowController.restartShow()                 }) {                 Text("Перезапустить показ")             }              // Отображаем текущую подсказку из контроллера             // Composable Bubble с контроллером автоматически управляет видимостью и настройками.             bubbleShowController.ShowBubbles()         }     }     

Модификатор .assignBubble() связывает ваши UI-компоненты с соответствующими данными подсказок в контроллере. Контроллер затем сам позаботится об определении targetComponentRect для каждой подсказки.

Нужно больше настроек?

Если вы предпочитаете иметь полный контроль и кастомизацию каждого пузыря в списке для показа, то используйте BubbleShowControllerExtended для контроля и BubbleDataExtended для настройки каждого пузыря.

Заключение

TAO Bubbles для Jetpack Compose – это простой, но мощный инструмент для создания интерактивных подсказок и туров по приложению. Благодаря гибкой настройке и удобному API, вы сможете значительно улучшить пользовательский опыт, помогая пользователям осваивать функционал вашего приложения легко и непринужденно.
Попробуйте TAO Bubbles в своем следующем проекте!

Скачать последний релиз и код демо-приложения https://github.com/lordtao/android-tao-bubbles

Лицензия MIT


ссылка на оригинал статьи https://habr.com/ru/articles/936122/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *