Jetpack Compose — Примечания к анимации: 4

Jetpack Compose — это революционное обновление для создания пользовательского интерфейса приложения для Android. Он использовал концепцию декларативного пользовательского интерфейса и привнес удовольствие в создание пользовательского интерфейса с помощью Kotlin — мечта многих разработчиков Android. Если вы новичок в Jetpack Compose, я рекомендую вам ознакомиться со следующими статьями:

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

С учетом сказанного, давайте начнем.

Введение

Мы пытаемся реализовать представление с двумя кнопками для увеличения и уменьшения числа на 1. Результат будет отображаться в середине кнопок с вертикальной анимацией. Посмотрите на результат:

Мы собираемся добиться этого с помощью AnimatedContent compose API.

AnimatedContent

AnimatedContent — это контейнер, который автоматически анимирует свое содержимое при изменении targetState. Взгляните на подпись:

  1. targetState : это универсальный тип, и всякий раз, когда значение изменяется, анимация запускается.
  2. modifier : Модификатор связывает содержимое внутри этого составного объекта с его родителем.
  3. transitionSpec : это тип ContentTransform, используемый в основном для определения EnterTransition и ExitTransitions.
  4. contentAlignment : чтобы определить выравнивание содержимого внутри content компонуемого.
  5. content : Может быть объединен с targetState параметром для предоставления обновленного значения.

Кроссфейд

Crossfade переключается между макетами на основе изменения значения его параметра targetState с анимацией кроссфейда. Взгляните на подпись:

  1. targetState: это общий тип, и всякий раз, когда значение изменяется, анимация запускается.
  2. modifier : Модификатор связывает содержимое внутри этого составного объекта с его родителем.
  3. animationSpecAnimationSpec для настройки анимации.
  4. content : можно комбинировать с targetState параметром для предоставления обновленного значения.

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

Простой компонуемый дизайн

Начнем с базовой конструкции. Нам нужны две кнопки: плюс и минус. Для этого мы используем компонуемые Box и Icon. Давайте создадим функцию CircleButton для повторного использования для обеих кнопок. Нужны три параметра:

  1. imageVector : Чтобы определить значок для отображения.
  2. contentDescription : Для специальных возможностей не обязательно. Лучшая практика.
  3. clickable : логическое значение, определяющее, можно ли нажать кнопку.
  4. 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
}

Прежде чем перейти к части дизайна, нам нужна пара расширений:

  1. getOpposite — эта функция возвращает альтернативное состояние ConTentType, например, если это WORK, то она вернет PARTY.
  2. 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.

  1. Нажмите здесь, чтобы просмотреть полный код реализации AnimatedContent.
  2. Пожалуйста, нажмите здесь, чтобы просмотреть полный код реализации Crossfade.

Анимация — интересная тема в Jetpack Compose, позволяющая сделать пользовательский интерфейс более плавным. Следите за новыми статьями об анимации в Jetpack Compose.

Бонус



На данный момент - все. Надеюсь, вы узнали что-то полезное. Спасибо за прочтение.