Flutter는 애니메이션을 통해 애플리케이션의 사용자 경험을 향상시킬 수 있는 다양한 도구와 위젯을 제공합니다. 애니메이션은 사용자 인터페이스의 생동감을 더해주고, 사용자와의 상호작용을 더욱 매끄럽게 만들어 줍니다. 이번 글에서는 Flutter에서 애니메이션을 적용하는 방법과 다양한 예제를 통해 이를 구현하는 방법에 대해 자세히 살펴보겠습니다.
1. 애니메이션의 기본 요소
Flutter에서 애니메이션을 구현하기 위해서는 두 가지 주요 요소가 필요합니다: Animation 객체와 AnimationController. AnimationController는 애니메이션의 실행을 제어하고, Animation 객체는 애니메이션의 현재 상태를 나타냅니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Basic Animation')),
body: Center(
child: BasicAnimationWidget(),
),
),
);
}
}
class BasicAnimationWidget extends StatefulWidget {
@override
_BasicAnimationWidgetState createState() => _BasicAnimationWidgetState();
}
class _BasicAnimationWidgetState extends State<BasicAnimationWidget> 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 = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.scale(
scale: _animation.value,
child: child,
);
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
);
}
}
위 코드는 기본적인 크기 변화 애니메이션을 구현한 예제입니다. AnimationController는 2초 동안 반복되는 애니메이션을 제어하며, CurvedAnimation을 사용하여 애니메이션에 곡선을 적용합니다. AnimatedBuilder는 애니메이션 값에 따라 위젯을 빌드합니다.
2. Tween 애니메이션
Tween은 애니메이션의 시작 값과 끝 값을 정의합니다. Tween을 사용하면 애니메이션 값이 범위 내에서 변화하도록 할 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Tween Animation')),
body: Center(
child: TweenAnimationWidget(),
),
),
);
}
}
class TweenAnimationWidget extends StatefulWidget {
@override
_TweenAnimationWidgetState createState() => _TweenAnimationWidgetState();
}
class _TweenAnimationWidgetState extends State<TweenAnimationWidget> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Color?> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = ColorTween(
begin: Colors.blue,
end: Colors.red,
).animate(_controller);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Container(
width: 100,
height: 100,
color: _animation.value,
);
},
);
}
}
위 코드는 ColorTween을 사용하여 색상이 파란색에서 빨간색으로 변화하는 애니메이션을 구현합니다. animate 메서드를 통해 AnimationController와 Tween을 연결합니다.
3. Hero 애니메이션
Hero 위젯은 화면 전환 간에 자연스러운 애니메이션을 제공합니다. 이를 통해 두 화면 간에 공유 요소를 애니메이션할 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
},
child: Hero(
tag: 'hero-widget',
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: Hero(
tag: 'hero-widget',
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
),
),
);
}
}
위 코드는 Hero 애니메이션을 사용하여 첫 번째 페이지에서 두 번째 페이지로 전환할 때 컨테이너의 크기가 변화하는 애니메이션을 구현합니다. Hero 위젯의 tag 속성을 사용하여 두 화면 간의 공유 요소를 식별합니다.
4. AnimatedContainer 위젯
AnimatedContainer 위젯은 상태 변화에 따라 애니메이션을 자동으로 적용하는 컨테이너입니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('AnimatedContainer Demo')),
body: Center(
child: AnimatedContainerWidget(),
),
),
);
}
}
class AnimatedContainerWidget extends StatefulWidget {
@override
_AnimatedContainerWidgetState createState() => _AnimatedContainerWidgetState();
}
class _AnimatedContainerWidgetState extends State<AnimatedContainerWidget> {
bool _selected = false;
void _toggle() {
setState(() {
_selected = !_selected;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _toggle,
child: AnimatedContainer(
width: _selected ? 200 : 100,
height: _selected ? 200 : 100,
color: _selected ? Colors.red : Colors.blue,
alignment: _selected ? Alignment.center : AlignmentDirectional.topCenter,
duration: Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
child: FlutterLogo(size: 75),
),
);
}
}
위 코드는 AnimatedContainer 위젯을 사용하여 상태 변화에 따라 크기와 색상이 변경되는 애니메이션을 구현합니다. 사용자가 컨테이너를 클릭하면 setState를 통해 애니메이션이 적용됩니다.
결론
Flutter에서 애니메이션을 적용하는 것은 사용자 인터페이스를 더욱 생동감 있게 만들고, 사용자 경험을 향상시키는 중요한 기술입니다. 기본 애니메이션 요소인 Animation 객체와 AnimationController를 사용하여 다양한 애니메이션을 구현할 수 있으며, Tween, Hero, AnimatedContainer 등 다양한 위젯을 활용하여 더욱 복잡한 애니메이션을 쉽게 만들 수 있습니다. 이러한 애니메이션 도구들을 적절히 활용하여 매력적이고 직관적인 사용자 인터페이스를 제공하는 애플리케이션을 만들어보세요.
'Flutter' 카테고리의 다른 글
Flutter의 상태 관리 패턴(State Management Patterns) (0) | 2024.07.25 |
---|---|
Flutter의 트랜지션(Transition) 효과 사용법 (0) | 2024.07.25 |
Flutter의 커스텀 위젯(Custom Widget) 만들기 (31) | 2024.07.24 |
Flutter의 테마(Theme) 적용 방법 (14) | 2024.07.24 |
Flutter의 시간 선택기(Time Picker) 사용법 (27) | 2024.07.24 |