Модификатор animateEnterExit()

Последнее обновление: 13.04.2024

Когда к компоненту AnimatedVisibility применяются анимации, они применяются ко всем вложенным компонентам. Однако специальная функция-модификатор animateEnterExit() позволяет определить анимацию на уровне отдельных компонентов. Как и в случае с AnimatedVisibility, этот модификатор позволяет объявлять анимацию появления и исчезновения компонента на экране. Но важно отметить, что этот модификатор применяется не сам по себе в любом месте пользовательского интерфейса, а только в рамках AnimatedVisibility.

Модификатор animateEnterExit() имеет следующее определение:

@ExperimentalAnimationApi
public open fun Modifier.animateEnterExit(
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = fadeOut() + shrinkOut(),
    label: String = "animateEnterExit"
): Modifier

Как и AnimatedVisibility, модификатор использует параметры enter и exit для определения анимации появления и исчезновения компонента на экране. Кроме того с помощью параметра label можно назначить текстовую метку. Поскольку данный модификатор является экспериментальным то при его использовании к компоненту следует применять аннотацию @ExperimentalAnimationApi

Пример применения модификатора animateEnterExit:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent @ExperimentalAnimationApi{
            val boxVisible = remember { mutableStateOf(true) }
            Column(Modifier.padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally) {
                AnimatedVisibility(
                    visible = boxVisible.value,
                    Modifier.padding(40.dp),
                    enter = EnterTransition.None,
                    exit = ExitTransition.None) {
                    Box(Modifier.animateEnterExit(
                        enter = slideInVertically(tween(durationMillis = 5000)),
                        exit = slideOutVertically(tween(durationMillis = 5000))
                    ).size(200.dp).background(Color.DarkGray))
                }
                Row(Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceEvenly) {
                    Button({boxVisible.value = true}, enabled = !boxVisible.value){ Text("Show", fontSize = 28.sp)}
                    Button({boxVisible.value = false}, enabled = boxVisible.value){ Text("Hide", fontSize = 28.sp)}
                }
            }
        }
    }
}

Здесь модификатор применяется к компоненту Box, который расположен внутри AnimatedVisibility:

AnimatedVisibility(
    visible = boxVisible.value,
    Modifier.padding(40.dp),
    enter = EnterTransition.None,
    exit = ExitTransition.None) {
        Box(Modifier.animateEnterExit(
            enter = slideInVertically(tween(durationMillis = 5000)),
            exit = slideOutVertically(tween(durationMillis = 5000))
        ).size(200.dp).background(Color.DarkGray))
}

Видимость компонента AnimatedVisibility привязана к переменной-состоянию boxVisible, значение которой переключается кнопками.

Поскольку для управления анимацией всецело используется модификатор animateEnterExit на компоненте Box, то для AnimatedVisibility наоборот отключаем анимацию:

enter = EnterTransition.None,
exit = ExitTransition.None

У компонента Box для анимации применяем функции slideInVertically и slideOutVertically

 Box(Modifier.animateEnterExit(
    enter = slideInVertically(tween(durationMillis = 5000)),
    exit = slideOutVertically(tween(durationMillis = 5000))
)

Таким образом при появлении компонент Box начнет медленно скользить сверху вниз в течение 5 секунд, а при изчезновении, наоборот, подниматься снизу вверх, пока не уйдет из области обзора.

Modifier.animateEnterExit и анимация в Jetpack Compose на Kotlin в Android

Аналогично можно было бы определить внутри AnimatedVisibility несколько компонентов с разными типами анимаций:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent @ExperimentalAnimationApi{
            val boxVisible = remember { mutableStateOf(true) }
            Column(Modifier.padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally) {
                AnimatedVisibility(
                    visible = boxVisible.value,
                    Modifier.padding(20.dp),
                    enter = EnterTransition.None,
                    exit = ExitTransition.None) {
                    Row{

                        Box(Modifier.animateEnterExit(
                            enter = slideInVertically(tween(durationMillis = 5000)),
                            exit = slideOutVertically(tween(durationMillis = 5000))
                        ).size(150.dp).background(Color.DarkGray))

                        Spacer(modifier = Modifier.width(20.dp))

                        Box(Modifier.animateEnterExit(
                            enter = fadeIn(tween(durationMillis = 5000)),
                            exit = fadeOut(tween(durationMillis = 5000))
                        ).size(150.dp).background(Color.DarkGray))
                    }
                }
                Row(Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceEvenly) {
                    Button({boxVisible.value = true}, enabled = !boxVisible.value){ Text("Show", fontSize = 28.sp)}
                    Button({boxVisible.value = false}, enabled = boxVisible.value){ Text("Hide", fontSize = 28.sp)}
                }
            }
        }
    }
}

В данном случае в AnimatedVisibility два компонента Box с разным набором анимаций. Первый Box для создания анимации использует функции slideInVertically() и slideOutVertically(), тогда как второй Box - функции fadeIn() и fadeOut()

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850