Jetpack Compose — Примечания к анимации: 4
Jetpack Compose — это революционное обновление для создания пользовательского интерфейса приложения для Android. Он использовал концепцию декларативного пользовательского интерфейса и привнес удовольствие в создание пользовательского интерфейса с помощью Kotlin — мечта многих разработчиков Android. Если вы новичок в Jetpack Compose, я рекомендую вам ознакомиться со следующими статьями:
Чтобы узнать больше об анимациях в составе реактивного ранца, прочитайте следующую статью из этой серии анимаций:
- «Jetpack Compose — Animated Notes: 1 — Изучение AnimatedVisibility в Compose»
- «Jetpack Compose — Animation Notes: 2 — Создание великолепного меню с Compose AnimatedVisibility и Animatable»
- “Jetpack Compose — Animation Notes: 3” — Изучение LaunchedEffect и InfiniteTransition в Compose
- «Jetpack Compose — Animation Notes: 4» — Вы здесь и сейчас
С учетом сказанного, давайте начнем.
Введение
Мы пытаемся реализовать представление с двумя кнопками для увеличения и уменьшения числа на 1. Результат будет отображаться в середине кнопок с вертикальной анимацией. Посмотрите на результат:
Мы собираемся добиться этого с помощью AnimatedContent
compose API.
AnimatedContent
AnimatedContent
— это контейнер, который автоматически анимирует свое содержимое при изменении targetState
. Взгляните на подпись:
targetState
: это универсальный тип, и всякий раз, когда значение изменяется, анимация запускается.modifier
: Модификатор связывает содержимое внутри этого составного объекта с его родителем.transitionSpec
: это типContentTransform
, используемый в основном для определенияEnterTransition
иExitTransitions
.contentAlignment
: чтобы определить выравнивание содержимого внутриcontent
компонуемого.content
: Может быть объединен сtargetState
параметром для предоставления обновленного значения.
Кроссфейд
Crossfade переключается между макетами на основе изменения значения его параметра targetState
с анимацией кроссфейда. Взгляните на подпись:
targetState
: это общий тип, и всякий раз, когда значение изменяется, анимация запускается.modifier
: Модификатор связывает содержимое внутри этого составного объекта с его родителем.animationSpec
—AnimationSpec
для настройки анимации.content
: можно комбинировать сtargetState
параметром для предоставления обновленного значения.
Чтобы лучше понять это, мы создадим компоновку для переключения между двумя значками по нажатию кнопки с плавной анимацией. Взгляни:
Простой компонуемый дизайн
Начнем с базовой конструкции. Нам нужны две кнопки: плюс и минус. Для этого мы используем компонуемые Box и Icon. Давайте создадим функцию CircleButton
для повторного использования для обеих кнопок. Нужны три параметра:
imageVector
: Чтобы определить значок для отображения.contentDescription
: Для специальных возможностей не обязательно. Лучшая практика.clickable
: логическое значение, определяющее, можно ли нажать кнопку.click
: лямбда-функция, которая будет вызываться по клику.
Посмотрите на реализацию:
Теперь мы можем использовать эту функцию в корневом компоновщике с соответствующим содержимым внутри Row
, чтобы раздувать их рядом. Взгляни:
@Composable fun NumberUpdateAnimationView(){ Row( verticalAlignment = Alignment.CenterVertically, ) { k CircleButton( imageVector = Icons.Default.Remove, contentDescription = "Minus", ){ } Spacer(modifier = Modifier.size(16.dp)) CircleButton( imageVector = Icons.Default.Add, contentDescription = "Add" ){ } } }
Посмотрите на вывод:
Затем нам нужно спроектировать Text
для отображения целочисленного значения. Мы используем remember
с mutableStateOf
для его определения. Мы будем обновлять значение, когда пользователь нажимает кнопку «плюс», и наоборот, кнопку «минус». Взгляни:
Посмотрите на вывод:
AnimatedContent
Теперь пришло время добавить анимацию к изменению содержимого. Сначала нам нужно обернуть компонуемый Text
внутри AnimatedContent
и использовать полученное значение для обновления текста. Взгляните на код:
AnimatedContent( targetState = displayNumber, ){ _displayNumber -> Text( text = "${_displayNumber}", fontSize = 24.sp, fontWeight = FontWeight(500), color = Color.Black ) }
Это применит анимацию по умолчанию к любому значению в targetState
. Посмотрите на вывод:
Наша цель здесь — добавить пользовательскую анимацию, такую как табло. Мы используем параметр transitionSpec
для определения пользовательской анимации входа и выхода при изменении содержимого. Взгляните на код ниже:
ContentTransform
используется для определения анимации входа и выхода. Мы смешали две анимации slideIn
с fadeIn
для анимации ввода нового значения и slideOut
и fadeOut
для анимации выхода. Это isreversed
, когда значение уменьшается. Посмотрите на вывод:
Посмотрите на код со всеми частями вместе:
Теперь, когда мы узнали, как анимировать содержимое, следующая часть этой статьи посвящена анимации изменений макета с помощью плавной анимации.
Состояния макета
Для простоты мы поддерживаем два состояния — работа и вечеринка через класс enum для представления соответствующего значка. У нас также есть кнопка для переключения между состояниями. Взгляните на класс перечисления:
enum class ConTentType{ WORK, PARTY }
Прежде чем перейти к части дизайна, нам нужна пара расширений:
getOpposite
— эта функция возвращает альтернативное состояниеConTentType
, например, если этоWORK
, то она вернетPARTY
.getDisplayString
— используется для отображения строк в зависимости от состояния.
fun ConTentType.getOpposite() = run { when(this){ ConTentType.PARTY -> ConTentType.WORK ConTentType.WORK -> ConTentType.PARTY } } fun ConTentType.getDisplayString() = run { when(this){ ConTentType.PARTY -> "Party" ConTentType.WORK -> "Work" } }
Простой компонуемый дизайн
Давайте начнем с базового дизайна с парой значков, основанных на состоянии ConTentType
, и кнопкой для обновления состояния. Взгляните на код:
Теперь давайте посмотрим на вывод:
Кроссфейд анимация
Теперь мы должны обернуть блок when с помощью CrossFade API и передать contenttype
как targetState
, чтобы всякий раз, когда происходит изменение в contenttype
, срабатывала анимация кроссфейда. Взгляни:
Пожалуйста, имейте в виду, что для работы функции необходимо использовать targetState
. В нашем случае это _contentType
. Посмотрите на вывод:
Если анимация слишком быстрая, вы можете контролировать продолжительность с помощью параметра animationSpec
параметра Crossfade
. Мы можем пройти tween
с продолжительностью в зависимости от требований.
Crossfade( targetState = contenttype, animationSpec = tween(durationMillis = 500) )
Теперь взгляните на вывод:
Конечная нота
Вот и все. Мы реализовали анимацию табло и анимацию плавного перехода между макетами с помощью AnimatedContent
и Crossfade
API, предоставляемых Jetpack Compose.
- Нажмите здесь, чтобы просмотреть полный код реализации AnimatedContent.
- Пожалуйста, нажмите здесь, чтобы просмотреть полный код реализации Crossfade.
Анимация — интересная тема в Jetpack Compose, позволяющая сделать пользовательский интерфейс более плавным. Следите за новыми статьями об анимации в Jetpack Compose.
Бонус
На данный момент - все. Надеюсь, вы узнали что-то полезное. Спасибо за прочтение.