[Android/Compose] Jetpack Compose Animation๐Ÿ”ฅ ๊ณต๋ถ€ํ•˜๊ธฐ

์ฐŒ๋‹ˆยท2023๋…„ 5์›” 17์ผ
0

Android(Compose)

๋ชฉ๋ก ๋ณด๊ธฐ
12/12
post-thumbnail

Compose CodeLab์„ ๋ณด๋ฉฐ ๋…ธ์…˜์— ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค (์‹ค์Šต ์ฝ”๋“œ๋งŒ ๋‹ค๋ฆ„)

animate*AsState

  • ๊ฐ’ ๋ณ€๊ฒฝ ์• ๋‹ˆ๋ฉ”์ด์…˜ (state ๋ณ€๊ฒฝ์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ)
@Composable
funanimateColorAsState(
    targetValue: Color, // animation ํƒ€๊ฒŸ
    animationSpec:AnimationSpec<Color> = colorDefaultSpring, // ์‹œ๊ฐ„์— ๋”ฐ๋ผ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์• ๋‹ˆ๋ฉ”์ด์…˜
    finishedListener: ((Color) -> Unit)? =null // ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์™„๋ฃŒ๋  ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๋Š” ์„ ํƒ์  ๋ฆฌ์Šค๋„ˆ
):State<Color> {
valconverter = remember(targetValue.colorSpace){
(Color.VectorConverter)(targetValue.colorSpace)
}
}
var clicked by remember {
         mutableStateOf(false)
    }
val buttonColors by animateColorAsState(if (clicked) Color.Yellow else Color.DarkGray)
Button(
		onClick = { clicked = !clicked },
    colors = ButtonDefaults.buttonColors(backgroundColor = buttonColors)
		   )
		{
        Text(text = if (clicked)"click" else "cancel", color = if(!clicked)Color.White else Color.Black)
		}

AnimatedVisibility

Button(
        onClick = { clicked = !clicked },
        colors = ButtonDefaults.buttonColors(backgroundColor = buttonColors)

    ) {
        Text(text = if (clicked)"click" else "cancel", color = if (!clicked)Color.White else Color.Black)
    }
AnimatedVisibility(visible = !clicked) {
    Box(
        modifier = Modifier.fillMaxWidth().background(color = MaterialTheme.colors.secondary).clip(RoundedCornerShape(20.dp)).padding(10.dp)
    ) {
        Text(
            text = "you clicked!!",
            color = Color.White
        )
    }
}
  • enterTransition, exitTransition, initialOffsetY, targetOffsetY , animationSpec๋“ฑ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•œ ์ปค์Šคํ…€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ€๋Šฅ

animationSpec ์ด๋ž€?

  • ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ปค์Šคํ…€ํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค
  • spring, tween, keyframes, repeatable / infiniteRepeatable, snap ๊ฐ€ ์กด์žฌ

animateContentSize

  • ์ฝ˜ํ…์ธ  ํฌ๊ธฐ ๋ณ€๊ฒฝ ์• ๋‹ˆ๋ฉ”์ด์…˜
  • ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์•„๋ฌด๊ฒƒ๋„ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ spring ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋…ธ์ถœ

  • animateContentSize ์ ์šฉ ํ›„

Transition API

  • animate*AsState์™€ ๋‹ฌ๋ฆฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์™„๋ฃŒ๋œ ์‹œ์  ์ถ”์  ๊ฐ€๋Šฅ
  • ๋‹ค์–‘ํ•œ transitionSpec ์ •์˜ ๊ฐ€๋Šฅ
  • updateTransition๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ์šฉ
@Composable
fun<T> updateTransition(
    targetState: T,
    label: String? =null
): Transition<T> {
valtransition = remember{Transition(targetState, label = label)}
transition.animateTo(targetState)
DisposableEffect(transition){
onDispose{
transition.onTransitionEnd()
}
    }
returntransition
}
  • animation target์˜ state์™€ label ์ „๋‹ฌ
var clicked by remember {
        mutableStateOf(true)
}

val transition = updateTransition(targetState = clicked, label = "")
val buttonColors by transition.animateColor(label = "") { clicked ->
    if (clicked) Color.Yellow else Color.DarkGray
}
val textColors by ta

Button(
        onClick = { clicked = !clicked },
        colors = ButtonDefaults.buttonColors(buttonColors)
  ) {
      Text(text = if (clicked)"click button!" else "cancel", color = if (!clicked)Color.White else Color.Black, modifier = Modifier.animateContentSize())
  

InfiniteTransition

  • ๋ฐ˜๋ณต์ ์ธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ€๋Šฅ
  • rememberInfiniteTransition๋ฅผ ์ด์šฉํ•ด ์„ ์–ธ
  • animate* ํ™•์žฅํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ’ ๋ณ€๊ฒฝ

color์— infiniteTransition ์ ์šฉํ•˜๊ธฐ!

val infiniteTransition = rememberInfiniteTransition()
            val buttonColors by infiniteTransition.animateColor(
                initialValue = Color.Yellow,
                targetValue = Color.DarkGray,
                animationSpec = infiniteRepeatable(
                    animation = keyframes {
                        durationMillis = 1000
                    },
                    repeatMode = RepeatMode.Restart
                )
            )
  • repeatMode = RepeatMode.Reverse

  • repeatMode = RepeatMode.Restart

Animatable

swipeToDismiss

  • ํ„ฐ์น˜ ์ž…๋ ฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜
  • [pointerInput](https://developer.android.com/reference/kotlin/androidx/compose/ui/input/pointer/package-summary?hl=ko#(androidx.compose.ui.Modifier).pointerInput(kotlin.Any,kotlin.coroutines.SuspendFunction1)) ์ˆ˜์ •์ž ์‚ฌ์šฉ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ๋“œ๋ž˜๊ทธํ•˜๋Š” ์†๋„๋ฅผ ์ถ”์ ๊ฐ€๋Šฅ
profile
์ฐŒ๋‹ˆ's develog

0๊ฐœ์˜ ๋Œ“๊ธ€