[Flutter]애니메이션-ImplicitAnimation란

임효진·2024년 5월 4일
0

Animations

목록 보기
1/2
post-thumbnail

플러터에서 애니메이션을 구현하는 방법 중 하나는 "암시적 애니메이션(Implicit Animations)"을 사용하는 것입니다. 암시적 애니메이션은 이름에서 알 수 있듯이 명시적으로 애니메이션의 모든 단계를 세세하게 제어할 필요 없이, 시작 상태와 끝 상태를 정의하고 나머지는 플러터 프레임워크에 맡기는 방식입니다.
플러터 내의 애니메이션 중에 가장 최하위의 난이도를 가집니다.

암시적 애니메이션이라는 말이 너무 어렵게 느껴질 수 있습니다, 간단하게 버튼을 누르면
버튼의 색상이 서서히 바뀌거나 사진이 점점 커지는 것과 같은 애니메이션을 보여줍니다.
난이도가 낮은 이유는 프로그램 자체가 '어떻게' 동작할지 알아서 처리해주니 '무엇을' 바꾸고 싶은지만 정하면 됩니다.

암시적 애니메이션의 특징

간편한 구현:
애니메이션을 적용할 위젯의 변화를 간단한 위젯 속성 변경으로 구현할 수 있습니다.
짧은 코드:
복잡한 애니메이션을 몇 줄의 코드로 구현할 수 있어 개발 속도가 향상됩니다.
프레임워크 지원:
플러터의 많은 위젯들이 암시적 애니메이션을 지원하도록 설계되어 있습니다.

주요 암시적 애니메이션 위젯

AnimatedContainer: 크기, 색상, 모서리 반경 등 다양한 속성을 애니메이션으로 변화시킬 수 있습니다.
AnimatedOpacity: 위젯의 투명도를 애니메이션으로 조절합니다.
TweenAnimationBuilder: 값의 범위를 애니메이션으로 중간 값을 자동으로 계산해줍니다.

예제 코드(회전하는 컨테이너)

import 'package:flutter/material.dart';

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

  
  State<ImplicitAnimationScreen> createState() =>
      _ImplicitAnimationScreenState();
}

class _ImplicitAnimationScreenState extends State<ImplicitAnimationScreen> {
  bool _visible = true;
  void _toggleVisibility() {
    setState(() {
      _visible = !_visible;
    });
  }

  
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        title: const Text('Implicit Animations'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RotatingContainer(size: size, visible: _visible),
            const SizedBox(height: 50),
            GoButton(onPressed: _toggleVisibility),
          ],
        ),
      ),
    );
  }
}

class RotatingContainer extends StatelessWidget {
  final Size size;
  final bool visible;

  const RotatingContainer({
    super.key,
    required this.size,
    required this.visible,
  });

  
  Widget build(BuildContext context) {
    return AnimatedContainer(
      curve: Curves.elasticOut,
      duration: const Duration(seconds: 2),
      width: size.width * 0.8,
      height: size.width * 0.8,
      transform: Matrix4.rotationZ(visible ? 1 : 0),
      transformAlignment: Alignment.center,
      decoration: BoxDecoration(
        color: visible ? Colors.red : Colors.amber,
        borderRadius: BorderRadius.circular(visible ? 100 : 0),
      ),
    );
  }
}

class GoButton extends StatelessWidget {
  final VoidCallback onPressed;

  const GoButton({super.key, required this.onPressed});

  
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      child: const Text('Go'),
    );
  }
}

TweenAnimationBuilder

TweenAnimationBuilder는 Flutter에서 애니메이션을 구현할 때 사용하는 도구 중 하나로, 특정 속성의 시작 값과 끝 값을 지정하면, 그 사이의 중간 값들을 자동으로 계산해주어 부드럽게 변화하게 만듭니다. TweenAnimationBuilder는 '암시적 애니메이션'의 한 예로, 복잡한 애니메이션 컨트롤러를 직접 관리할 필요 없이 간단하게 애니메이션 효과를 추가할 수 있습니다.

TweenAnimationBuilder을 사용하는 이유?

유연성: TweenAnimationBuilder는 다양한 타입의 데이터에 대한 애니메이션을 구현할 때 더 유연하게 사용할 수 있습니다. 반면, AnimatedContainer는 주로 컨테이너의 시각적 속성 변화에 제한됩니다.
구현: TweenAnimationBuilder는 값의 변화를 직접 관리하고, 해당 값을 사용하여 위젯을 빌드해야 합니다. AnimatedContainer는 속성을 변경하는 것만으로 애니메이션 효과가 자동으로 적용됩니다.
적용 범위: TweenAnimationBuilder는 하나의 속성에 대한 애니메이션을 더 세밀하게 제어할 수 있습니다. AnimatedContainer는 컨테이너의 다양한 속성을 한 번에 애니메이션화할 수 있어, 여러 속성의 변경을 간편하게 처리할 수 있습니다.

TweenAnimationBuilder는 AnimatedContainer보다 난이도가 약간은 더 있는 편입니다.
일반적으로 암시적 애니메이션에 내가 원하는 애니메이션 속성이 없는 경우에 많이 사용합니다.
TweenAnimationBuilder는 개발자가 직접 'Tween'을 정의하고 애니메이션의 시작과 끝 값을 명시해야 합니다. 즉 애니메이션 진행에 따라 값을 계산하고 그 값을 사용하여 동적으로 위젯을 빌드하는데 사용합니다.

TweenAnimationBuilder는 세 가지 주요 구성 요소를 받습니다:

Tween:
애니메이션의 시작과 끝 값을 정의합니다. ColorTween, Tween, Tween 등 다양한 타입의 트윈을 사용할 수 있습니다.
Duration:
애니메이션의 전체 지속 시간을 설정합니다.
Builder:
실제 위젯을 빌드하는 함수로, 애니메이션의 현재 값에 따라 어떻게 위젯을 그릴지 정의합니다. 이 함수는 애니메이션의 현재 값을 파라미터로 받아서 위젯을 반환합니다.

예제 코드(이미지의 색상이 점차적으로 변경되는 예제)

import 'package:flutter/material.dart';

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


State<ImplicitAnimationScreen> createState() =>
    _ImplicitAnimationScreenState();
}

class _ImplicitAnimationScreenState extends State<ImplicitAnimationScreen> {
bool _visible = true;
void _toggleVisibility() {
  setState(() {
    _visible = !_visible;
  });
}


Widget build(BuildContext context) {
  final size = MediaQuery.of(context).size;
  return Scaffold(
    appBar: AppBar(
      title: const Text('Implicit Animations'),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const ColorChangingImage(),
          const SizedBox(height: 50),
          GoButton(onPressed: _toggleVisibility),
        ],
      ),
    ),
  );
}
}

class ColorChangingImage extends StatelessWidget {
const ColorChangingImage({super.key});


Widget build(BuildContext context) {
  return TweenAnimationBuilder(
    tween: ColorTween(
      begin: Colors.yellow,
      end: Colors.blue,
    ),
    curve: Curves.bounceInOut,
    duration: const Duration(seconds: 5),
    builder: (context, Color? color, child) {
      return Image.network(
        'https://storage.googleapis.com/cms-storage-bucket/780e0e64d323aad2cdd5.png',
        color: color,![]
        colorBlendMode: BlendMode.colorBurn,
      );
    },
  );
}
}

공식문서 :https://api.flutter.dev/flutter/animation/Tween-class.html

profile
핫바리임

0개의 댓글