플러터에서 애니메이션을 구현하는 방법 중 하나는 "암시적 애니메이션(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는 Flutter에서 애니메이션을 구현할 때 사용하는 도구 중 하나로, 특정 속성의 시작 값과 끝 값을 지정하면, 그 사이의 중간 값들을 자동으로 계산해주어 부드럽게 변화하게 만듭니다. TweenAnimationBuilder는 '암시적 애니메이션'의 한 예로, 복잡한 애니메이션 컨트롤러를 직접 관리할 필요 없이 간단하게 애니메이션 효과를 추가할 수 있습니다.
유연성: TweenAnimationBuilder는 다양한 타입의 데이터에 대한 애니메이션을 구현할 때 더 유연하게 사용할 수 있습니다. 반면, AnimatedContainer는 주로 컨테이너의 시각적 속성 변화에 제한됩니다.
구현: TweenAnimationBuilder는 값의 변화를 직접 관리하고, 해당 값을 사용하여 위젯을 빌드해야 합니다. AnimatedContainer는 속성을 변경하는 것만으로 애니메이션 효과가 자동으로 적용됩니다.
적용 범위: TweenAnimationBuilder는 하나의 속성에 대한 애니메이션을 더 세밀하게 제어할 수 있습니다. AnimatedContainer는 컨테이너의 다양한 속성을 한 번에 애니메이션화할 수 있어, 여러 속성의 변경을 간편하게 처리할 수 있습니다.
TweenAnimationBuilder는 AnimatedContainer보다 난이도가 약간은 더 있는 편입니다.
일반적으로 암시적 애니메이션에 내가 원하는 애니메이션 속성이 없는 경우에 많이 사용합니다.
TweenAnimationBuilder는 개발자가 직접 'Tween'을 정의하고 애니메이션의 시작과 끝 값을 명시해야 합니다. 즉 애니메이션 진행에 따라 값을 계산하고 그 값을 사용하여 동적으로 위젯을 빌드하는데 사용합니다.
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