Animation
Animation은 사용자 경험을 향상시키고, 앱의 인터페이스를 더 직관적이고 반응적으로 만드는 데 중요한 역할을 합니다.
나타나거나 사라지는 애니메이션
AnimatedVisibility 함수를 사용하면 visible 속성에 넣은 값에 따라 컴포저블을 숨기거나 표시할 수 있습니다.
@Composable
fun AnimatedVisibility(
visible: Boolean,
modifier: Modifier = Modifier,
enter: EnterTransition = fadeIn() + expandVertically(),
exit: ExitTransition = fadeOut() + shrinkVertically(),
label: String = "AnimatedVisibility",
content: @Composable AnimatedVisibilityScope.() -> Unit
): Unit
- visible : visible 설정
- modifier : 애니메이션에 적용할 modifier 설정
- enter : 표시되는 애니메이션에 사용할 Transition 설정 ('+'으로 결합 가능)
- exit : 소멸되는 애니메이션에 사용할 Transition 설정 ('+'으로 결합 가능)
- label : 해당 함수에 붙일 label 설정
- content : 이를 대상으로 하는 content 설정
EnterTransition 및 ExitTransition 예시
AnimatedVisibility 사용 예시
@Composable
fun AnimationExample() {
var helloWorldVisible by remember { mutableStateOf(true) }
Column(
modifier = Modifier
.fillMaxSize()
) {
AnimatedVisibility(
visible = helloWorldVisible,
enter = expandVertically() + slideInHorizontally(),
exit = slideOutHorizontally()
) {
Text(text = "Hello World!")
}
RadioButtonWithText(text = "Hello World 보이기", selected = helloWorldVisible) {
helloWorldVisible = true
}
RadioButtonWithText(text = "Hello World 감추기", selected = !helloWorldVisible) {
helloWorldVisible = false
}
...
}
}
배경색 또는 알파값에 애니메이션 적용
animate(...)AsState 함수를 사용하면 설정해놓은 targetValue가 변경됨에 따라 상태가 달라지는 애니메이션을 만들 수 있습니다.
또한, updateTransition 함수를 통해서도 Transition의 인스턴스를 만들고 기억하며 상태를 업데이트할 수 있습니다.
@Composable
fun <T> updateTransition(
targetState: T,
label: String? = null
): Transition<T>
@Composable
fun animateColorAsState(
targetValue: Color,
animationSpec: AnimationSpec<Color> = colorDefaultSpring,
label: String = "ColorAnimation",
finishedListener: ((Color) -> Unit)? = null
): State<Color>
@Composable
inline fun <S> Transition<S>.animateColor(
noinline transitionSpec:
@Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Color> = { spring() },
label: String = "ColorAnimation",
targetValueByState: @Composable() (state: S) -> Color
): State<Color>
@Composable
fun animateFloatAsState(
targetValue: Float,
animationSpec: AnimationSpec<Float> = defaultAnimation,
visibilityThreshold: Float = 0.01f,
label: String = "FloatAnimation",
finishedListener: ((Float) -> Unit)? = null
): State<Float>
@Composable
inline fun <S> Transition<S>.animateFloat(
noinline transitionSpec:
@Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Float> = { spring() },
label: String = "FloatAnimation",
targetValueByState: @Composable (state: S) -> Float
): State<Float>
animate(...)AsState 함수 사용 예시
- "흰색" 라디오 버튼이 선택되어 있는 경우 : 흰색 배경색 + 알파값이 1f
- "노란색" 라디오 버튼이 선택되어 있는 경우 : 노란색 배경색 + 알파값이 0.5f
@Composable
fun AnimationExample() {
// animateColorAsState를 통해 isYellow 상태에 따라 color 설정
val color by animateColorAsState(
targetValue = if (isYellow) Color.Yellow else Color.White, label = "Color"
)
// animateFloatAsState를 통해 isYellow 상태에 따라 alpha 설정
val alpha by animateFloatAsState(
targetValue = if (isYellow) 0.5f else 1.0f, label = "Alpha"
)
...
Column(
modifier = Modifier
.fillMaxWidth()
.background(color)
.alpha(alpha)
.padding(16.dp)
) {
Text(text = "배경색 설정")
RadioButtonWithText(text = "흰색", selected = !isYellow) {
isYellow = false
}
RadioButtonWithText(text = "노란색", selected = isYellow) {
isYellow = true
}
...
}
}
@Composable
fun RadioButtonWithText(
text: String,
color: Color = Color.Black,
selected: Boolean,
onClick: () -> Unit
) {
Row(
modifier = Modifier.selectable(
selected = selected,
onClick = onClick
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(selected = selected, onClick = onClick)
Text(text = text, color = color)
}
}
updateTransition 함수 사용 예시
- "일반 모드" 라디오 버튼이 선택되어 있는 경우 : 흰색 배경색 + 검정색 글씨색 + 알파값이 0.5f
- "다크 모드" 라디오 버튼이 선택되어 있는 경우 : 노란색 배경색 + 흰색 글씨색 + 알파값이 1f
@Composable
fun AnimationExample() {
var isDarkMode by remember { mutableStateOf(false) }
// updateTransition을 통해 isDarkMode 상태 관리
val transition = updateTransition(
targetState = isDarkMode,
label = "Dark Mode Transition"
)
// transition에 대해 animateColor를 호출해 배경색 설정
val backgroundColor by transition.animateColor(label = "Dark Mode Background Color") { state ->
when (state) {
false -> Color.White
true -> Color.Black
}
}
// transition에 대해 animateColor를 호출해 글자색 설정
val textColor by transition.animateColor(label = "Dark Mode Text Color") { state ->
when (state) {
false -> Color.Black
true -> Color.White
}
}
// transition에 대해 animateFloat을 호출해 alpha 값 설정
val alphaValue by transition.animateFloat(label = "Dark Mode Alpha Value") { state ->
when (state) {
false -> 0.5f
true -> 1f
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
.alpha(alphaValue)
.padding(16.dp)
) {
Text(text = "다크 모드 설정", color = textColor)
RadioButtonWithText(
text = "일반 모드",
color = textColor,
selected = !isDarkMode
) {
isDarkMode = false
}
RadioButtonWithText(
text = "다크 모드",
color = textColor,
selected = isDarkMode
) {
isDarkMode = true
}
...
}
}
@Composable
fun RadioButtonWithText(
text: String,
color: Color = Color.Black,
selected: Boolean,
onClick: () -> Unit
) {
Row(
modifier = Modifier.selectable(
selected = selected,
onClick = onClick
),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(selected = selected, onClick = onClick)
Text(text = text, color = color)
}
}
728x90
반응형
'안드로이드 > Compose' 카테고리의 다른 글
[Android] Compose - 아키텍처 (0) | 2024.06.05 |
---|---|
[Android] Compose - 부수 효과 (0) | 2024.05.27 |
[Android] Compose - ConstraintLayout (0) | 2024.05.17 |
[Android] Compose - Lazy layout (0) | 2024.05.15 |
[Android] Compose 컴포넌트 - Image (0) | 2024.05.13 |