AnimatedBuilder

샤워실의 바보·2024년 1월 21일
0

Flutter Animation

목록 보기
10/31
post-thumbnail
import 'package:flutter/material.dart';

class ExplicitAnimationsScreen extends StatefulWidget {
  const ExplicitAnimationsScreen({super.key});

  
  State<ExplicitAnimationsScreen> createState() =>
      _ExplicitAnimationsScreenState();
}

class _ExplicitAnimationsScreenState extends State<ExplicitAnimationsScreen>
    with SingleTickerProviderStateMixin {
  late final AnimationController _animationController = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 10),
  );

  void _play() {
    _animationController.forward();
  }

  void _pause() {
    _animationController.stop();
  }

  void _rewind() {
    _animationController.reverse();
  }

  
  void initState() {
    super.initState();
  }

  
  Widget build(BuildContext context) {
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: const Text('Explicit Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedBuilder(
              animation: _animationController,
              builder: (context, child) {
                return Opacity(
                  opacity: _animationController.value,
                  child: Container(
                    color: Colors.amber,
                    width: 400,
                    height: 400,
                  ),
                );
              },
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _play,
                  child: const Text("Play"),
                ),
                ElevatedButton(
                  onPressed: _pause,
                  child: const Text("Pause"),
                ),
                ElevatedButton(
                  onPressed: _rewind,
                  child: const Text("Rewind"),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

이 Flutter 코드에서 AnimatedBuilder 위젯은 애니메이션 효과를 구현하는 데 중요한 역할을 합니다. AnimatedBuilder는 Flutter의 명시적 애니메이션 구조에서 핵심적인 부분으로, 성능과 효율성 측면에서 여러 장점을 제공합니다.

AnimatedBuilder의 효율성:

  1. 성능 최적화:

    • AnimatedBuilder는 애니메이션이 있는 부분만 재구축(rebuild)합니다. 이는 전체 위젯 트리가 아닌 필요한 부분만 업데이트하므로 성능이 향상됩니다.
    • 예를 들어, _animationController의 값이 변경될 때마다 AnimatedBuilder에 의해 builder 함수만 호출되어 관련 위젯이 업데이트됩니다. 이는 불필요한 렌더링을 줄여주어 성능에 유리합니다.
  2. 부모 위젯과의 분리:

    • AnimatedBuilder를 사용하면 애니메이션 로직을 부모 위젯으로부터 분리할 수 있습니다. 이는 코드의 가독성과 유지 보수성을 높이는 데 도움이 됩니다.
    • 애니메이션 코드가 부모 위젯의 build 메서드 밖에 있으면, 부모 위젯의 다른 변경 사항이 애니메이션 위젯에 영향을 주지 않습니다.

AnimatedBuilder의 작동 방식:

  • AnimatedBuilderanimation 속성으로 Animation 객체(여기서는 _animationController)를 받습니다.
  • builder 속성은 BuildContextWidget (선택적으로 child 위젯)을 매개변수로 하는 함수입니다.
  • animation 객체의 값이 변경될 때마다 builder 함수가 호출되어, 해당 변화를 반영한 새로운 위젯 트리를 생성합니다.

이 코드에서의 사용 예:

  • _animationController는 애니메이션의 진행 상태를 제어합니다.
  • AnimatedBuilder_animationController의 값에 따라 Opacity 위젯의 opacity 속성을 업데이트합니다.
  • 사용자가 'Play', 'Pause', 'Rewind' 버튼을 눌러 _animationController를 제어함에 따라, AnimatedBuilderOpacity 위젯의 투명도를 애니메이션화합니다.
import 'package:flutter/material.dart';

class ExplicitAnimationsScreen extends StatefulWidget {
  const ExplicitAnimationsScreen({super.key});

  
  State<ExplicitAnimationsScreen> createState() =>
      _ExplicitAnimationsScreenState();
}

class _ExplicitAnimationsScreenState extends State<ExplicitAnimationsScreen>
    with SingleTickerProviderStateMixin {
  late final AnimationController _animationController = AnimationController(
    vsync: this,
    duration: const Duration(seconds: 2),
  );

  late final Animation<Color?> _color =
      ColorTween(begin: Colors.amber, end: Colors.red)
          .animate(_animationController);

  void _play() {
    _animationController.forward();
  }

  void _pause() {
    _animationController.stop();
  }

  void _rewind() {
    _animationController.reverse();
  }

  
  void initState() {
    super.initState();
  }

  
  Widget build(BuildContext context) {
    print("build");
    return Scaffold(
      appBar: AppBar(
        title: const Text('Explicit Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedBuilder(
              animation: _color,
              builder: (context, child) {
                return Container(
                  color: _color.value,
                  width: 400,
                  height: 400,
                );
              },
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _play,
                  child: const Text("Play"),
                ),
                ElevatedButton(
                  onPressed: _pause,
                  child: const Text("Pause"),
                ),
                ElevatedButton(
                  onPressed: _rewind,
                  child: const Text("Rewind"),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

_animationController.valueTween을 사용하는 것 사이에는 몇 가지 중요한 차이점이 있으며, 각각의 사용은 상황에 따라 달라질 수 있습니다. 이 두 방법은 Flutter에서 애니메이션을 구현하는 데 사용되는 기본적인 개념입니다.

  1. _animation.value 사용:

    • AnimationControllervalue 속성은 0과 1 사이의 값을 가지며, 애니메이션의 현재 진행 상태를 나타냅니다.
    • 이 방법은 간단한 애니메이션에 적합하며, 애니메이션 값의 범위가 0에서 1 사이일 때 유용합니다.
    • 예를 들어, 투명도나 회전 애니메이션과 같이 값의 범위가 제한적인 경우에 적합합니다.
  2. Tween 사용:

    • Tween은 시작 값과 종료 값 사이를 보간하는 객체입니다. 이를 사용하여 더 넓은 범위의 값을 생성할 수 있습니다.
    • Tween은 두 값 사이의 전체 범위를 보간하며, 이를 통해 더 복잡하고 세밀한 애니메이션을 만들 수 있습니다.
    • 예를 들어, 크기, 위치, 색상 등의 변화를 나타내는 데 사용할 수 있습니다. Tween<double>, Tween<Offset>, Tween<Color> 등 다양한 유형의 Tween이 있습니다.
    • TweenAnimationController와 함께 사용되며, Tween.animate() 메서드를 통해 Animation 객체를 생성합니다.

사용 사례에 따른 선택:

  • 간단하고 범위가 제한적인 애니메이션의 경우, _animation.value 사용이 더 간단하고 직관적일 수 있습니다.
  • 보다 복잡한 애니메이션 또는 더 넓은 범위의 값 변화가 필요한 경우, Tween을 사용하는 것이 더 유연하고 강력합니다.

이 Flutter 코드는 명시적 애니메이션을 사용하여 색상 변화를 구현한 예제입니다. 이전 코드와 비교했을 때, 이 코드의 주요 차이점은 ColorTween을 사용하여 색상 변화를 애니메이션화한다는 것입니다. ColorTween은 시작 색상에서 끝 색상으로 부드럽게 변화하는 애니메이션을 만들기 위해 사용됩니다.

ColorTween의 사용:

  • ColorTweenTween<Color>의 특수한 형태로, 색상 값 사이를 보간합니다.
  • beginend 속성을 통해 시작 색상(여기서는 Colors.amber)과 끝 색상(여기서는 Colors.red)을 정의합니다.
  • animate 메서드를 사용하여 AnimationController와 연결합니다. 이렇게 하면, 컨트롤러의 값에 따라 색상이 보간됩니다.

ColorTween의 장점:

  • ColorTween을 사용하면 색상 변화를 간편하게 애니메이션화할 수 있습니다.
  • 이 방법은 복잡한 애니메이션 로직이나 색상 계산을 직접 작성할 필요 없이 부드러운 색상 전환을 구현할 수 있습니다.
  • Tween을 사용하면 시작 값과 끝 값 사이의 중간 값들을 자동으로 계산하여, 애니메이션의 부드러운 전환을 보장합니다.

이 코드는 이전 코드보다 ColorTween을 사용하여 색상 변화를 보다 간편하고 효율적으로 구현합니다. 이 접근 방식은 애니메이션 효과를 더욱 풍부하고 다양하게 만들 수 있으며, Flutter에서 복잡한 애니메이션을 구현할 때 유용합니다. 개발자가 색상 변화와 같은 시각적 효과를 쉽게 구현할 수 있도록 도와주는 강력한 기능입니다.

profile
공부하는 개발자

0개의 댓글