앱의 콘텐츠를 스크롤하면 스크롤 방향에 따라 플로팅 액션 버튼이 확장되고 축소되는 것을 알 수 있다.

TODO 2-1을 찾아서 이것이 어떻게 작동하는지 확인하자. HomeFloatingActionButton 컴포저블 안에 있다. “EDIT”라는 텍스트는 if 문을 사용하여 표시하거나 숨긴다.

if (extended) {
    Text(
        text = stringResource(R.string.edit),
        modifier = Modifier
            .padding(start = 8.dp, top = 3.dp)
    )
}

이 가시성 변경에 애니메이션을 적용하는 것은 if를 AnimatedVisibility 컴포저블로 간단히 바꾸는 것뿐이다.

AnimatedVisibility(extended) {
    Text(
        text = stringResource(R.string.edit),
        modifier = Modifier
            .padding(start = 8.dp, top = 3.dp)
    )
}

앱을 실행하고 지금 FAB(Floating Action Button)가 어떻게 확장되고 축소되는지 확인하자.

찰스 생각: 코드랩에서 주어진 내용으로는 아직 FAB 확장/축소를 확인할 수가 없다.

37a613b87156bfbe.gif

AnimatedVisibility는 지정된 Boolean 값이 변경될 때마다 애니메이션을 실행한다. 기본적으로 AnimatedVisibility는 페이드 인 및 확장하여 요소를 표시하고 페이드 아웃 및 축소하여 요소를 숨긴다. 이 동작은 FAB를 사용하는 이 예제에서 잘 작동하지만 동작을 커스터마이징 할 수도 있다.

FAB를 클릭하면 “Edit feature is not supported(편집 기능이 지원되지 않습니다)”라는 메시지가 표시된다. 또한 AnimatedVisibility를 사용하여 나타났다가 사라지는 애니메이션이 실행된다. 이 애니메이션을 커스터마이징하여 요소가 위에서 안으로 들어가고, 위로 미끄러지도록 하는 방법을 살펴보자.

TODO 2-2를 찾아 EditMessage 컴포저블에서 코드를 확인하자.

AnimatedVisibility(
    visible = shown
) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        color = MaterialTheme.colors.secondary,
        elevation = 4.dp
    ) {
        Text(
            text = stringResource(R.string.edit_message),
            modifier = Modifier.padding(16.dp)
        )
    }
}

애니메이션을 커스터마이징 하려면 AnimatedVisibility 컴포저블에 enter 및 exit 매개변수를 추가한다.

enter 매개변수는 EnterTransition의 인스턴스여야 한다. 이 예제에서는 SlideInVertically 함수를 사용하여 EnterTransition을 만들 수 있다. 이 함수를 사용하면 initialOffsetY 및 animationSpec 매개변수로 추가하여 커스터마이징이 가능하다. initialOffsetY는 초기 위치를 반환하는 람다식이여야 한다. 람다는 요소의 높이에 해당하는 인자 하나를 수신하므로, 간단히 음수를 반환할 수 있다. SlideInVertically를 사용할 때 슬라이드 인 후 대상 오프셋은 항상 0(픽셀)이다. initialOffsetY는 절대값 또는 람다 함수를 통해 요소 전체 높이의 백분율로 지정할 수 있다.

animationSpec은 EnterTransition 및 ExitTransition을 포함한 많은 애니메이션 API의 공통 매개변수다. 다양한 AnimationSpec 타입 중 하나를 전달하여, 시간 경과에 따라 애니메이션 값이 어떻게 변경되어야 하는지 지정할 수 있다. 이 예제에서는 간단히 시간(duration) 기반의 AnimationSpec을 사용한다. 그것은 tween 함수로도 만들 수 있다. 지속 시간은 150ms이고 easing은 LinearOutSlowInEasing이다.

이징(Easing)은 애니메이션의 분수를 조정하는 방법이다. 이징을 사용하면 전환 요소가 일정한 속도로 이동하는 대신 속도를 높이거나 낮출 수 있다.

마찬가지로 exit 매개변수에 대해 slideOutVertically 함수를 사용할 수 있다. SlideOutVertically는 초기 오프셋이 0이라고 가정하므로 targetOffsetY만 지정하면 된다. animationSpec 매개변수에 대해 동일한 tween 함수를 사용하지만 지속 시간은 250ms이고 FastOutLinearInEasing의 easing이 있다.

결과 코드는 아래와 같아야 한다.

AnimatedVisibility(
    visible = shown,
    enter = slideInVertically(
        // 오프셋이 -(전체높이)에서 0으로 슬라이딩 하여 내려온다.
        initialOffsetY = { fullHeight -> -fullHeight },
        animationSpec = tween(durationMillis = 150, easing = LinearOutSlowInEasing)
    ),
    exit = slideOutVertically(
        // 오프셋이 0에서 -(전체높이)로 슬라이딩 하여 올라간다.
        targetOffsetY = { fullHeight -> -fullHeight },
        animationSpec = tween(durationMillis = 250, easing = FastOutLinearInEasing)
    )
) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        color = MaterialTheme.colors.secondary,
        elevation = 4.dp
    ) {
        Text(
            text = stringResource(R.string.edit_message),
            modifier = Modifier.padding(16.dp)
        )
    }
}

앱을 실행하고 FAB를 다시 클릭하자. 이제 메시지가 상단에서 안팎으로 미끄러지는 것을 볼 수 있다.

76895615b43b9263.gif
카테고리: Compose

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.