[Flutter] 올바른 애니메이션 구현 방법 선택하기

Cody Yun
6 min readAug 10, 2023

--

본 아티클은 플러터 공식 유튜브 채널에 업로드된 “How to choose which Flutter Animation Widget is right for you? — Flutter in Focus” 영상의 내용을 학습한 후 정리하기 위한 목적으로 작성되었습니다.

https://www.youtube.com/watch?v=GXIJJkq_H8g

1. 들여가며

플러터로 개발한 앱에 애니메이션을 포함하기로 결정했다면, 어떤 방식으로 애니메이션을 구현하는게 적절한지 파악하는것이 중요합니다. 플러터는 로우 레벨 애니메이션과 하이 레벨의 애니메이션을 제공하고 있으며, 애니메이션과 관련된 다양한 패키지를 pub.dev에서 찾아볼 수도 있습니다.

2. 두 가지 유형의 애니메이션

드로잉 기반의 애니메이션과 코드 기반의 애니메이션이 존재합니다. 코드 기반의 애니메이션은 행, 열, 색상, 스타일 등의 처리합니다. 코드 기반의 애니메이션은 기존 속성에서 새로운 속성으로 전환하는 경우 많이 사용됩니다. 드로잉 기반의 애니메이션은 그림입니다. 게임 캐릭터와 같이 누군가 그린것과 같은 애니메이션입니다. 속성의 전환을 사용하는 코드 기반의 에니메이션과는 달리 코드로 표현하기 어려운 변형을 시키는 경우가 이에 해당하며 Rive,나 Lottie와 같은 도구를 사용해 만들어진 애니메이션을 플러터에서 사용하는 경우가 많습니다.

3. 코드 기반의 애니메이션

코드 기반의 애니메이션은 암시적(Implicit) 애니메이션과 명시적(Explicit) 애니메이션으로 나뉩니다. 암시적 애니메이션은 AnimatedContainer와 같은 위젯을 사용해서 구현되는데 현재 값에서 새 값으로 전환되는 애니메이션을 놀랍도록 손쉽게 구현할 수 있게 해줍니다.

// 암시적 애니메이션
Widget build(BuildContext context) {
return AnimatedContainer(
decoration: BoxDecoration(
// 중략
),
transform: Matrix4.identity()
..translate(size/2, size/2)
..multiply(Matrix4.rorationZ(math.pi / 4)
..translate(-size/2, -size/2),
duration: Duration(seconds: 1),
);
}

명시적 애니메이션은 AnimationController가 필요합니다. ‘명시적’이라고 하는 이유는 애니메이션을 ‘명시적'으로 시작할 때 애니메이션이 재생되기 때문입니다.

// 명시적 애니메이션
var _controller = AnimationController(
duration: Duration(secodns: 1),
vsync: this,
)
// 중략
_controller.forward()

명시적 애니메이션은 암시적 애니메이션으로 할 수 있는것 뿐만아니라 그 이상의 애니메이션을 구현할 수 있습니다. 명시적 애니메이션은 상태와 함께 사용되는 경우가 많기 때문에 StatefulWidget에서 주로 사용되고, 암시적 애니메이션은 상태와 무관하게 빌드 시점에 애니메이션이 시작됨으로 StatelessWidget에서 주로 사용합니다. 이러한 이유로 애니메이션을 구현한 코드의 간결함은 암시적 애니메이션이 더 간결합니다.

4. 암시적 애니메이션과 명시적 애니메이션 선택하기

암시적 애니메이션과 명시적 애니메이션을 선택할 때 아래 질문을 해볼 수 있습니다.

Q. 애니메이션이 특정 화면에 있을 동안 계속 반복 되나요?
Q. 애니메이션이 불연속적(Discontinuous)인가요?
(작은 원이 커졌다가 다시 작은 원에서 시작해 커지는것과 같은 애니메이션)
Q. 여러 위젯이 조화롭게 함께 애니메이션 되나요?

위 질문에 하나라도 ‘네' 라고 대답한다면 명시적 애니메이션이 필요합니다. 모두 ‘아니오'라고 대답한다면 암시적 애니메이션으로 구현할 수 있습니다.

5. 구현에 필요한 애니메이션 위젯 찾기

암시적 애니메이션을 사용하기로 결정했다면 필요한 애니메이션을 제공하는 플러터 내장 애니메이션 위젯을 찾을 차례입니다. AnimatedContainer는 플러터 내장 암시적 애니메이션을 구현한 위젯 중 강력한 기능을 제공합니다. 그 외에도 다양한 암시적 애니메이션 구현을 위한 위젯을 제공하는데, 제공되는 암시적 애니메이션으로 필요한 애니메이션을 구현할 수 없다면 TweenAnimationBuilder를 사용해 사용자 지정 애니메이션을 만들 수 있습니다.

명시적 애니메이션을 사용하기로 결정했다면 필요한 애니메이션을 제공하는 플러터 내장 명시적 애니메이션 위젯을 사용할 수 있습니다. 일반적으로 FooTransition 이라고 부릅니다. Foo는 애니메이션에 사용할 다양한 속성을 의미합니다. FooTransition에는 AlignTransition, DecoratedBoxTranstion, FadeTranstion 등이 있습니다. FooTranstion 중 원하는 애니메이션을 찾을 수 없다면 다음은 구현할 애니메이션이 위젯 독립적으로 실행되는지, 다른 위젯과 함께 실행되는지를 질문할 차례입니다. 독립적으로 실행된다면 AnimatedWidget을 확장해서 애니메이션을 구현할 수 있고 아니라면 AnimatedBuilder를 사용할 수 있습니다. 끝으로 이러한 위젯들이 성능적으로 문제가 있다면 CustomPainter를 사용합니다. 플러터 내부 렌더링 로직을 이해하고 CustomPainter를 잘 사용하면 문제가 없지만 그렇지 않은 경우 여러 문제가 발생할 수 있어 주의해야 합니다.

6. 정리하기

플러터 애니메이션을 공부하기에 앞서 명시적 애니메이션과 암시적 애니메이션이 나오면서 모호한 부분이 있었습니다. 플러터팀에서 제공하는 영상은 플러터가 빠르게 발전하고 있고, 3년 전 영상 임에도 불구하고 여전히 유효한 내용이었습니다. AnimatedContainer, TweenAnimationBuilder, AnimationController, FooTranstion, AnimatedWidget만 알아도 애니메이션과 관련된 요구 사항은 손쉽게 해결할 수 있을것 같아 겁을 좀 더는 계기가 됐습니다.

--

--

Cody Yun

I wanna be a full stack software engineer at the side of user-facing application.