IT기술/플러터 (flutter)

Flutter 애니메이션 완벽 가이드: 기본부터 고급 활용법까지

후스파 2025. 7. 11. 05:58
반응형

플러터(Flutter)는 직관적이고 강력한 애니메이션 프레임워크를 제공해, 앱의 UI/UX를 한층 더 생동감 있게 만들 수 있습니다.
아래에서 기본 애니메이션 원리부터 고급 활용법과 실전 베스트 프랙티스까지 단계별로 정리합니다.


플러터 애니메이션의 기본 구조

핵심 개념

  • AnimationController: 애니메이션의 실행, 정지, 반복 등 전체 흐름을 제어하는 객체
  • Animation: 애니메이션 값의 변화를 나타내는 객체 (ex. Animation, Animation)
  • Tween: 시작값과 끝값을 정의, Animation과 결합해 실제 애니메이션 값 생성
  • CurvedAnimation: 선형(linear)이 아닌 다양한 곡선(가속, 감속, 바운스 등)으로 애니메이션 효과 부여

기본 예제

class AnimationExample extends StatefulWidget {
  @override
  _AnimationExampleState createState() => _AnimationExampleState();
}

class _AnimationExampleState extends State with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );
    _animation = Tween(begin: 0, end: 300).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ))
    ..addListener(() {
      setState(() {});
    });
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('기본 애니메이션')),
      body: Center(
        child: Container(
          width: _animation.value,
          height: _animation.value,
          color: Colors.blue,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          if (_controller.isCompleted) {
            _controller.reverse();
          } else {
            _controller.forward();
          }
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}
  • Tween으로 0에서 300까지 값을 변화시키며, Container의 크기가 부드럽게 변함
  • CurvedAnimation으로 자연스러운 움직임 구현
  • addListener에서 setState 호출로 프레임마다 UI 갱신

암시적(Implicit) vs 명시적(Explicit) 애니메이션

암시적 애니메이션

  • 위젯 자체가 애니메이션을 내장하고 있어 코드가 간단함
  • 대표 위젯: AnimatedContainer, AnimatedOpacity, AnimatedPositioned
AnimatedContainer(
  duration: Duration(seconds: 1),
  width: isBig ? 200 : 100,
  height: isBig ? 200 : 100,
  color: isBig ? Colors.red : Colors.green,
  curve: Curves.easeInOut,
)

상태가 바뀔 때마다 자동으로 애니메이션 적용

명시적 애니메이션

  • AnimationController, Tween 등으로 세밀하게 제어
  • 복잡한 애니메이션, 다단계 효과, 사용자 정의 커브 등 고급 효과 구현에 적합

고급 애니메이션 활용법

여러 애니메이션 조합

  • TweenSequence: 여러 구간의 애니메이션을 순차적으로 연결
  • Multiple AnimationController: 여러 속성(위치, 크기, 투명도 등)을 동시에 제어

커스텀 애니메이션 곡선

  • 내장 커브(Curves.bounceIn, Curves.elasticOut 등) 외에 직접 커브 정의 가능
  • CurvedAnimation으로 다양한 움직임 연출

Hero 애니메이션

  • 화면 전환 시 동일한 위젯이 자연스럽게 이동
  • 두 화면에 동일한 Hero(tag: ...) 위젯 사용

Physics-based Animation

  • 실제 물리 법칙(스프링, 중력 등)을 적용
  • SpringSimulation, BouncingScrollPhysics 등 활용

AnimatedBuilder, AnimatedWidget 활용

  • AnimatedBuilder: 애니메이션 값에 따라 여러 위젯을 효율적으로 갱신
  • AnimatedWidget: 애니메이션을 직접 위젯에 적용해 코드 간결화

실전 예시: 화면 전환, 리스트 애니메이션

화면 전환 애니메이션

Navigator.push(context, PageRouteBuilder(
  pageBuilder: (context, animation, secondaryAnimation) => DetailScreen(),
  transitionsBuilder: (context, animation, secondaryAnimation, child) {
    var begin = Offset(1.0, 0.0);
    var end = Offset.zero;
    var curve = Curves.ease;
    var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
    return SlideTransition(position: animation.drive(tween), child: child);
  },
));

리스트 아이템 Fade 애니메이션

FadeTransition(
  opacity: animation,
  child: ListTile(title: Text('애니메이션 아이템')),
)

애니메이션 성능 최적화 및 베스트 프랙티스

핵심 최적화 기법

  • RepaintBoundary로 애니메이션 영역 분리해 불필요한 리빌드 최소화
  • 애니메이션은 목적이 명확할 때만 사용 (과도한 효과는 UX 저하)
  • AnimatedBuilder, AnimatedWidget으로 불필요한 setState 호출 방지
  • dispose()에서 AnimationController 반드시 해제
  • 다양한 기기에서 부드러운 동작을 위해 실제 기기에서 테스트

성능 최적화 예시

RepaintBoundary(
  child: AnimatedBuilder(
    animation: _controller,
    builder: (context, child) {
      return Transform.rotate(
        angle: _controller.value * 2 * math.pi,
        child: child,
      );
    },
    child: Container(
      width: 100,
      height: 100,
      color: Colors.blue,
    ),
  ),
)

마무리

플러터의 애니메이션 시스템은 간단한 효과부터 복잡한 커스텀 모션, 화면 전환, 물리 기반 애니메이션까지 모두 지원합니다.
기본 구조와 원리를 익히고, 암시적/명시적 애니메이션, Hero, Physics 등 다양한 기법을 조합하면 더욱 풍부하고 매력적인 앱 UI/UX를 구현할 수 있습니다. 사용자 경험을 향상시키는 자연스럽고 의미 있는 애니메이션을 통해 앱의 완성도를 한층 높여보세요.

반응형