์ ๋๋ฉ์ด์ - animateAsState์์ AnimatedVisibility๊น์ง
์ง๋ ๊ธ์์ ๋ค๋ฃฌ ์ฒดํฌ๋ฐ์ค๋ฅผ ๋ค์ ๋ณด์. ์ง๊ธ์ ์ฒดํฌํ๋ฉด ๊ทธ๋ฅ "๋" ํ๊ณ ์ํ๊ฐ ๋ฐ๋๋ค. ์๋ฃ๋ ํ ์ผ์ ๋ฐฐ๊ฒฝ์์ด ์ค๋ฅด๋ฅต ๋ฐ๋๊ณ , ์ญ์ ํ๋ฉด ์ฅ ์ฌ๋ผ์ง๊ฒ ๋ง๋ค์ด๋ณด์.
์ง๊ธ ์ฝ๋๋ ๊ฐ์ด ๋ฐ๋๋ฉด ๊ทธ๋ฅ ๋ฐ๋ก ๋ฐ๋๋ค
Row(
modifier = Modifier
.fillMaxWidth()
.background(if (todo.isDone) Color(0xFFE0F2E9) else Color.Transparent)
) {
// ...
}์ฒดํฌ๋ฐ์ค๋ฅผ ๋๋ฅด๋ฉด todo.isDone์ด ๋ฐ๋๊ณ , ๊ทธ ์ฆ์ ๋ฐฐ๊ฒฝ์์ด ์ด๋ก์ โ ํฌ๋ช
์ฌ์ด๋ฅผ ๋๋ ๋๊ธฐ๋ฉด์ ๋ฐ๋๋ค. ์์ด ์์ํ ๋ณํ๊ธธ ๋ฐ๋๋ค๋ฉด ์ ์์ฒด๋ฅผ "์์ํ ๋ฐ๋๋ ๊ฐ"์ผ๋ก ๋ง๋ค์ด์ผ ํ๋ค.
animateColorAsState - ๊ฐ ํ๋๋ฅผ ์์ํ ๋ฐ๊ฟ์ค๋ค
val backgroundColor by animateColorAsState(
targetValue = if (todo.isDone) Color(0xFFE0F2E9) else Color.Transparent,
label = "todoBackground"
)
Row(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
) {
// ...
}[์ด๋ฏธ์ง: ์ฒดํฌ๋ฐ์ค๋ฅผ ๋๋ฅด๋ ์๊ฐ ๋ฐฐ๊ฒฝ์์ด ์์ํ ์ด๋ก์์ผ๋ก ๋ฐ๋์ด๊ฐ๋ ์ค๊ฐ ๋จ๊ณ ํ๋ฉด]
animateColorAsState๋ targetValue๊ฐ ๋ฐ๋ ๋๋ง๋ค "์ง๊ธ ๊ฐ์์ ๋ชฉํ ๊ฐ๊น์ง" ์ค๊ฐ ์์๋ค์ ํ๋ ์๋ง๋ค ๊ณ์ฐํด์ ๋๋ ค์ค๋ค. ์ฝ๋์์ ํ๋ ์ผ์ if๋ก ๋ชฉํ ์์ ์ ํด์ฃผ๋ ๊ฒ๋ฟ์ด๊ณ , ์ค์ ๋ก ์์ํ ๋ฐ๋๋ ์ ๋๋ฉ์ด์
์ ์ด ํจ์๊ฐ ์์์ ์ฒ๋ฆฌํ๋ค. Int, Dp, Float ๊ฐ์ ๊ฐ์๋ ๊ฐ๊ฐ animateIntAsState, animateDpAsState, animateFloatAsState๊ฐ ์๋๋ฐ, ์ ๋ถ "๋ชฉํ๊ฐ์ ์ฃผ๋ฉด ๊ทธ ๊ฐ๊น์ง ์์ํ ๋ณํ๋ State๋ฅผ ๋๋ ค์ค๋ค"๋ ๊ฐ์ ์๋ฆฌ๋ค.
AnimatedVisibility - ์๊ธฐ๊ณ ์ฌ๋ผ์ง๋ ๊ฒ ์์ฒด์ ์ ๋๋ฉ์ด์
์ญ์ ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ทธ ํญ๋ชฉ์ด ๋ฆฌ์คํธ์์ ๋ฐ๋ก ์ฌ๋ผ์ง๋๋ฐ, ์ค๋ฅด๋ฅต ์ ํ๋ฉด์ ์ฌ๋ผ์ง๊ฒ ํด๋ณด์.
items(todoList, key = { it.id }) { todo ->
var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
visible = visible,
exit = shrinkVertically() + fadeOut()
) {
Row(
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
) {
// ...
IconButton(onClick = {
visible = false
}) {
Icon(imageVector = Icons.Default.Delete, contentDescription = "์ญ์ ")
}
}
}
}animateColorAsState๋ "๊ฐ ํ๋"๊ฐ ์์ํ ๋ฐ๋๋ ๊ฑฐ์๋๋ฐ, AnimatedVisibility๋ ๊ทธ ์์ ๋ด์ฉ ์ ์ฒด๊ฐ ๋ํ๋๊ฑฐ๋ ์ฌ๋ผ์ง๋ ๊ณผ์ ์์ฒด๋ฅผ ์ ๋๋ฉ์ด์
์ผ๋ก ๋ค๋ฃฌ๋ค. exit = shrinkVertically() + fadeOut()์ "์ฌ๋ผ์ง ๋ ์ธ๋ก๋ก ์ค์ด๋ค๋ฉด์ ๋์์ ํฌ๋ช
ํด์ง๋ค"๋ ๋ป์ด๋ค. visible์ ๋ฐ๋ก false๋ก ๋ฐ๊พธ๋ ๋์ , ์ ๋๋ฉ์ด์
์ด ๋๋ ๋๊น์ง๋ ํ๋ฉด์ ๋จ์์๋ค๊ฐ ๋๋๊ณ ๋์ ์ค์ ๋ก ๋ฆฌ์คํธ์์ ๋นผ๋ ์์ผ๋ก ์ฐ๋ฉด ๋ ์์ฐ์ค๋ฝ๋ค(์ง๊ธ ์์ ๋ ๊ฐ๋จํ visible๋ง ๋ฐ๊พธ๋ ๋ฒ์ ์ด๋ค).
Transition - ์ฌ๋ฌ ๊ฐ์ ํ๋์ ํ์ด๋ฐ์ผ๋ก ๋ฌถ์ด์ ์์ง์ด๊ธฐ
์ ํ๋, ๋ณด์ด๊ธฐ/๊ฐ์ถ๊ธฐ ํ๋์ฉ์ animate*AsState์ AnimatedVisibility๋ก ์ถฉ๋ถํ๋ค. ๊ทผ๋ฐ "์ฒดํฌ๋ ๋ ๋ฐฐ๊ฒฝ์๋ ๋ฐ๋๊ณ ๋์์ ์์ด์ฝ๋ ์ปค์ก๋ค๊ฐ ์์์ง๊ณ "์ฒ๋ผ ์ฌ๋ฌ ๊ฐ์ด ๊ฐ์ ํ์ด๋ฐ์ผ๋ก ๋ฌถ์ฌ์ ์์ง์ฌ์ผ ํ๋ฉด updateTransition์ ์ด๋ค.
val transition = updateTransition(targetState = todo.isDone, label = "todoState")
val backgroundColor by transition.animateColor(label = "bg") { isDone ->
if (isDone) Color(0xFFE0F2E9) else Color.Transparent
}
val scale by transition.animateFloat(label = "scale") { isDone ->
if (isDone) 1.1f else 1f
}updateTransition์ด todo.isDone์ด๋ผ๋ ํ๋์ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก, ๊ทธ ์ํ์ ๋ฌถ์ธ ์ฌ๋ฌ ์ ๋๋ฉ์ด์
๊ฐ(backgroundColor, scale)์ ํ ๋ฒ์ ๊ด๋ฆฌํด์ค๋ค. ๊ฐ๊ฐ ๋ฐ๋ก animateColorAsState, animateFloatAsState๋ฅผ ์ผ์ ๋๋ณด๋ค, "ํ๋์ ์ํ ์ ํ์ ๋ฌถ์ธ ์ ๋๋ฉ์ด์
๋ค"์ด๋ผ๋ ๊ด๊ณ๊ฐ ์ฝ๋์ ๋ ๋ถ๋ช
ํ๊ฒ ๋๋ฌ๋๋ค.
์ ๋ฆฌ
- ๊ฐ ํ๋๊ฐ ์์ํ ๋ฐ๋์ด์ผ ํ๋ฉด
animate*AsState(animateColorAsState,animateDpAsState๋ฑ) - ๋ญ๊ฐ ๋ํ๋๊ฑฐ๋ ์ฌ๋ผ์ง๋ ๊ณผ์ ์์ฒด๋ฅผ ์ ๋๋ฉ์ด์
์ผ๋ก ๋ค๋ฃจ๋ ค๋ฉด
AnimatedVisibility - ์ฌ๋ฌ ์ ๋๋ฉ์ด์
๊ฐ์ด ํ๋์ ์ํ ์ ํ์ ๋ฌถ์ฌ์ ๊ฐ์ด ์์ง์ฌ์ผ ํ๋ฉด
updateTransition
๋ค์ ๊ธ์์๋ ์ ๋๋ฉ์ด์ ์ฒ๋ผ ๋์ ๋ณด์ด๋ ๊ฒ ์๋๋ผ, ํ๋ฉด์ด ๋ฒ๋ฒ ์ด์ง ์๊ฒ "๋ถํ์ํ ๋ฆฌ์ปดํฌ์ง์ "์ ์ค์ด๋ ๋ฐฉ๋ฒ์ ๋ณด๊ฒ ๋ค.
