Компонент Crossfade позволяет анимировать замену одного компонента на другой. Функция компонента Crossfade принимает следующие параметры:
@Composable public fun <T> Crossfade( targetState: T, modifier: Modifier = Modifier, animationSpec: FiniteAnimationSpec<Float> = tween(), label: String = "Crossfade", content: @Composable (T) -> Unit ): Unit
targetState
: целевое состояние анимации. При каждом его изменении запускается анимация
modifier
: функции модификаторов, которые применяются к компоненту
animationSpec
: определение анимации
label
: текстовая метка анимации
content
: задает содержимое компонента
Рассмотрим небольшой пример:
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.Crossfade import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize 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.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.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) { AnimatedVisibility( visible = boxVisible.value, Modifier.padding(20.dp), enter = fadeIn(tween(5000)), exit = fadeOut(tween(5000))) { Box(Modifier.size(150.dp).background(Color.DarkGray)) } Crossfade(targetState = boxVisible, animationSpec = tween(5000)) { visible -> when (visible.value) { true -> Button({boxVisible.value = false }){ Text("Hide", fontSize = 28.sp)} false -> Button({boxVisible.value = true }){ Text("Show", fontSize = 28.sp)} } } } } } }
Здесь состояние для управления анимацией определено в виде переменной boxVisible:
val boxVisible = remember { mutableStateOf(true) }
Компонент AnimatedVisibility управляет видимостью вложенного компонента Box и для анимации использует функции fadeIn()
и fadeOut()
:
AnimatedVisibility( visible = boxVisible.value, Modifier.padding(20.dp), enter = fadeIn(tween(5000)), exit = fadeOut(tween(5000))) { Box(Modifier.size(150.dp).background(Color.DarkGray)) }
Затем идет вызов компонента Crossfade
Crossfade(targetState = boxVisible, animationSpec = tween(5000)) { visible -> when (visible.value) { true -> Button({boxVisible.value = false }){ Text("Hide", fontSize = 28.sp)} false -> Button({boxVisible.value = true }){ Text("Show", fontSize = 28.sp)} } }
Здесь Crossfade привязан к значению переменной-состояния boxVisible и при ее изменении запускает анимацию. Параметр animationSpec
в данном случае задает анимацию продолжительностью в 5000 миллисекунд.
Функция установки содержимого компонента Crossfade принимает один параметр - текущее значение состояния. В данном случае это параметр visible
, но в реальности через этоот параметр
передается значение boxVisible. А с помощью конструкции when мы решаем, при каком значении состояния отобразить тот или иной компонент. То есть если состояние равно
true
, то отображается кнопка Hide с кодом переключения состояния в false. А если состояние равно false
, то отображается кнопка Show с кодом переключения состояния в true
В итоге при нажатии на кнопку произойдет изменение состояния boxVisible. Поскольку Crossfade привязан к boxVisible, то произойдет перерисовка Crossfade, и соответственно мы увидим новую кнопку.