Flutter Animation


Flutter에서 애니메이션은 UI의 동적 변화를 매끄럽고 시각적으로 매력적으로 만드는 데 매우 중요한 역할을 합니다. 애니메이션을 통해 사용자 경험을 향상시키고, 사용자 인터페이스를 더 직관적으로 만들 수 있습니다. 이 글에서는 Flutter 애니메이션의 기본 개념부터 고급 기능까지 쉽게 설명하겠습니다.

1. Flutter 애니메이션 개요

Flutter에서 애니메이션은 일반적으로 AnimationAnimationController를 중심으로 구성됩니다. 기본적으로 Flutter 애니메이션은 다음과 같은 요소로 이루어져 있습니다:

  • Animation: 애니메이션의 값이 시간에 따라 어떻게 변하는지를 정의합니다.
  • AnimationController: 애니메이션의 상태를 관리하며, 애니메이션의 시작, 정지 및 제어를 담당합니다.
  • Tween: 애니메이션이 시작과 끝 사이의 값 변화를 정의합니다.
  • AnimatedWidget: 애니메이션의 상태를 위젯에 적용하는 역할을 합니다.
  • AnimationBuilder: 애니메이션의 값에 따라 위젯을 동적으로 변경하는 데 사용됩니다.

2. 기본 애니메이션

2.1. FadeTransition (투명도 애니메이션)

FadeTransition을 사용하면 위젯의 투명도를 애니메이션으로 변경할 수 있습니다.

예제 코드:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FadeTransitionDemo(),
    );
  }
}

class FadeTransitionDemo extends StatefulWidget {
  @override
  _FadeTransitionDemoState createState() => _FadeTransitionDemoState();
}

class _FadeTransitionDemoState extends State<FadeTransitionDemo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    _animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Fade Transition Demo')),
      body: Center(
        child: FadeTransition(
          opacity: _animation,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }

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

2.2. SlideTransition (슬라이딩 애니메이션)

SlideTransition을 사용하면 위젯이 화면의 특정 방향으로 슬라이드하도록 애니메이션을 적용할 수 있습니다.

예제 코드:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SlideTransitionDemo(),
    );
  }
}

class SlideTransitionDemo extends StatefulWidget {
  @override
  _SlideTransitionDemoState createState() => _SlideTransitionDemoState();
}

class _SlideTransitionDemoState extends State<SlideTransitionDemo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    _animation = Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset.zero).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Slide Transition Demo')),
      body: Center(
        child: SlideTransition(
          position: _animation,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.red,
          ),
        ),
      ),
    );
  }

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

3. 고급 애니메이션

3.1. AnimatedBuilder (애니메이션 빌더)

AnimatedBuilder를 사용하면 애니메이션의 상태를 기반으로 여러 위젯을 동적으로 업데이트할 수 있습니다.

예제 코드:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AnimatedBuilderDemo(),
    );
  }
}

class AnimatedBuilderDemo extends StatefulWidget {
  @override
  _AnimatedBuilderDemoState createState() => _AnimatedBuilderDemoState();
}

class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    _animation = Tween<double>(begin: 0.0, end: 100.0).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AnimatedBuilder Demo')),
      body: Center(
        child: AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return Container(
              width: _animation.value,
              height: _animation.value,
              color: Colors.green,
            );
          },
        ),
      ),
    );
  }

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

3.2. AnimatedWidget (애니메이션 위젯)

AnimatedWidget을 사용하면 애니메이션 상태를 관리하며 위젯의 속성을 애니메이션 값에 따라 업데이트할 수 있습니다.

예제 코드:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AnimatedWidgetDemo(),
    );
  }
}

class AnimatedWidgetDemo extends StatefulWidget {
  @override
  _AnimatedWidgetDemoState createState() => _AnimatedWidgetDemoState();
}

class _AnimatedWidgetDemoState extends State<AnimatedWidgetDemo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    _animation = Tween<double>(begin: 0.0, end: 100.0).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('AnimatedWidget Demo')),
      body: Center(
        child: MyAnimatedBox(animation: _animation),
      ),
    );
  }

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

class MyAnimatedBox extends AnimatedWidget {
  MyAnimatedBox({required Animation<double> animation}) : super(listenable: animation);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Container(
      width: animation.value,
      height: animation.value,
      color: Colors.blue,
    );
  }
}

4. 애니메이션의 상태 관리

Flutter에서 애니메이션 상태를 관리하기 위해 다양한 방법을 사용할 수 있습니다. 기본적으로 AnimationController를 사용하여 애니메이션의 상태를 제어할 수 있습니다. AnimationController는 애니메이션의 재생, 정지, 속도 조절 등을 관리합니다.

AnimationController 설정

late AnimationController _controller;

@override
void initState() {
  super.initState();
  _controller = AnimationController(
    duration: const Duration(seconds: 2),
    vsync: this,
  );
}
  • duration: 애니메이션의 전체 지속 시간을 설정합니다.
  • vsync: 애니메이션의 동기화를 처리하는 TickerProvider를 지정합니다.

애니메이션 제어

@override
void initState() {
  super.initState();
  _controller = AnimationController(
    duration: const Duration(seconds: 2),
    vsync: this,
  )..repeat(reverse: true);  // 애니메이션을 반복하며 역방향으로 재생
}

@override
void dispose() {
  _controller.dispose();
  super.dispose();
}
  • repeat(): 애니메이션을 반복합니다.
  • dispose(): 애니메이션이 더 이상 필요하지 않을 때 메모리 누수를 방지하기 위해 dispose 메서드에서 컨트

Leave a Reply

Your email address will not be published. Required fields are marked *