Анимация сенсорной обратной связи, как у Spotify в Jetpack Compose
May 04 2023
Создайте эффект прыгающего клика в Jetpack Compose
Крайне важно показать пользователю обратную связь о кликах, бла-бла-бла. Короче говоря, мне нравится эффект отскакивающего клика Spotify больше, чем эффект Ripple по умолчанию, поэтому давайте сделаем это Попутно мы изучим некоторые модификаторы и анимацию… Чтобы сделать это, мы создайте многоразовый модификатор (похожий на кликабельный модификатор), который уменьшает масштаб и непрозрачность при нажатии на элемент пользовательского интерфейса. Я продолжу и приведу весь код, а затем объясню его… Вот и все, давайте использовать его Вот и все, я надеюсь вам понравился блог ❤️.

Очень важно показать пользователю отзыв о клике, бла-бла-бла. Короче говоря, мне нравится эффект прыгающего клика Spotify больше, чем эффект Ripple по умолчанию, так что давайте сделаем это
Попутно мы изучим некоторые модификаторы и анимацию…

Для этого мы создадим многоразовый Modifier
модификатор (похожий на кликабельный), который уменьшает масштаб и непрозрачность при нажатии на элемент пользовательского интерфейса.
Я продолжу и приведу весь код, а затем объясню его…
/**
* Adds a bouncing click effect to a Composable.
*
* @param enabled whether the UI element should be enabled and clickable
* @param onClick the action to perform when the UI element is clicked
*/
fun Modifier.bouncingClickable(
enabled: Boolean = true,
onClick: () -> Unit
) = composed {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val animationTransition = updateTransition(isPressed, label = "BouncingClickableTransition")
val scaleFactor by animationTransition.animateFloat(
targetValueByState = { pressed -> if (pressed) 0.94f else 1f },
label = "BouncingClickableScaleFactorTransition",
)
val opacity by animationTransition.animateFloat(
targetValueByState = { pressed -> if (pressed) 0.7f else 1f },
label = "BouncingClickableOpacityTransition"
)
this
.graphicsLayer {
this.scaleX = scaleFactor
this.scaleY = scaleFactor
this.alpha = opacity
}
.clickable(
interactionSource = interactionSource,
indication = null,
enabled = enabled,
onClick = onClick
)
}
- Затем, поскольку у нас есть несколько анимаций, которые мы хотим запустить, когда
isPressed == true
, мы используемupdateTransition()
это, предоставляя нам функции расширения для запуска нескольких анимаций. - Чтобы создать анимацию, мы используем
animateFloat()
расширение для создания двух анимаций, одну дляscaleFactor
и одну дляopacity
того, что мы будем использовать для анимации нашего элемента пользовательского интерфейса. - Чтобы изменить масштаб и альфа-канал, мы использовали
graphicsLayer
модификатор, который обычно используется для применения преобразований и анимации к элементу пользовательского интерфейса. ( прочитайте эту замечательную статью, чтобы узнать больше ) - Наконец, мы добавляем модификатор clickable для обработки щелчка и удаляем эффект ряби по умолчанию, установив
indication
для параметра значениеnull
Вот и все, воспользуемся
Box(
modifier = Modifier
.bouncingClickable {
println("Clicked...")
}
.size(100.dp)
.clip(CircleShape)
.background(Color.Black)
) {}
val scaleFactor by animationTransition.animateFloat(
targetValueByState = { pressed -> if (pressed) 0.94f else 1f },
label = "BouncingClickableScaleFactorTransition",
transitionSpec = {
spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
}
)
Вот и все, надеюсь, вам понравился блог ❤️