Flutter 학습: 애니메이션 및 그래픽
Flutter에서는 다양한 애니메이션과 그래픽을 쉽게 구현할 수 있는 기능을 제공합니다. 이번 글에서는 기본 애니메이션, 고급 애니메이션, 그리고 커스텀 페인터를 사용한 그림 그리기에 대해 알아보겠습니다.
1. 기본 애니메이션: Animation, AnimationController, Tween
기본 애니메이션을 구현하기 위해서는 Animation, AnimationController, Tween을 사용합니다. AnimationController는 애니메이션의 실행과 제어를 담당하고, Tween은 시작 값과 끝 값을 정의하여 애니메이션의 변화를 설정합니다.
기본 애니메이션 예제: 간단한 애니메이션을 통해 버튼을 누를 때마다 크기가 변하는 애니메이션을 구현해보겠습니다.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AnimationExample(),
);
}
}
class AnimationExample extends StatefulWidget {
@override
_AnimationExampleState createState() => _AnimationExampleState();
}
class _AnimationExampleState extends State<AnimationExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 300).animate(_controller)
..addListener(() {
setState(() {});
});
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Basic Animation Example'),
),
body: Center(
child: Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_controller.isCompleted) {
_controller.reverse();
} else {
_controller.forward();
}
},
child: Icon(Icons.play_arrow),
),
);
}
}
위의 예제에서 AnimationController와 Tween을 사용하여 버튼을 누를 때마다 애니메이션이 실행되고, Container의 크기가 변합니다.
2. 고급 애니메이션: AnimatedBuilder, Hero 애니메이션, Staggered 애니메이션
AnimatedBuilder: AnimatedBuilder는 애니메이션을 효율적으로 구성하기 위해 사용되는 위젯으로, 애니메이션의 빌드 함수를 정의합니다.
AnimatedBuilder 예제:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AnimatedBuilderExample(),
);
}
}
class AnimatedBuilderExample extends StatefulWidget {
@override
_AnimatedBuilderExampleState createState() => _AnimatedBuilderExampleState();
}
class _AnimatedBuilderExampleState extends State<AnimatedBuilderExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 300).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AnimatedBuilder Example'),
),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_controller.isCompleted) {
_controller.reverse();
} else {
_controller.forward();
}
},
child: Icon(Icons.play_arrow),
),
);
}
}
Hero 애니메이션: Hero 위젯은 두 화면 간의 전환 애니메이션을 쉽게 구현할 수 있게 해줍니다.
Hero 애니메이션 예제:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstScreen(),
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Center(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
child: Hero(
tag: 'hero-example',
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Hero(
tag: 'hero-example',
child: Container(
width: 300,
height: 300,
color: Colors.blue,
),
),
),
);
}
}
Staggered 애니메이션: Staggered 애니메이션은 여러 애니메이션을 순차적으로 실행하는 방법입니다.
Staggered 애니메이션 예제:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: StaggeredAnimationExample(),
);
}
}
class StaggeredAnimationExample extends StatefulWidget {
@override
_StaggeredAnimationExampleState createState() => _StaggeredAnimationExampleState();
}
class _StaggeredAnimationExampleState extends State<StaggeredAnimationExample> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation1;
late Animation<double> _animation2;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 4),
vsync: this,
);
_animation1 = Tween<double>(begin: 0, end: 200).animate(
CurvedAnimation(parent: _controller, curve: Interval(0.0, 0.5, curve: Curves.easeIn)),
);
_animation2 = Tween<double>(begin: 0, end: 200).animate(
CurvedAnimation(parent: _controller, curve: Interval(0.5, 1.0, curve: Curves.easeOut)),
);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Staggered Animation Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedBuilder(
animation: _animation1,
builder: (context, child) {
return Container(
width: _animation1.value,
height: 50,
color: Colors.blue,
);
},
),
SizedBox(height: 20),
AnimatedBuilder(
animation: _animation2,
builder: (context, child) {
return Container(
width: _animation2.value,
height: 50,
color: Colors.red,
);
},
),
],
),
),
);
}
}
3. 커스텀 페인터: CustomPainter, 그림 그리기
Flutter에서는 CustomPainter를 사용하여 화면에 직접 그림을 그릴 수 있습니다. CustomPainter는 복잡한 그래픽을 그리기 위해 사용됩니다.
CustomPainter 사용 예제:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CustomPainterExample(),
);
}
}
class CustomPainterExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('CustomPainter Example'),
),
body: Center(
child: CustomPaint(
size: Size
'프로그래밍 > Flutter' 카테고리의 다른 글
[Flutter] 11. Flutter의 "퍼블리싱 및 배포" (0) | 2024.06.26 |
---|---|
[Flutter] 10. Flutter의 "테스트 및 디버깅" (0) | 2024.06.26 |
[Flutter] 8. Flutter의 "데이터베이스 및 로컬 저장소" (0) | 2024.06.26 |
[Flutter] 7. Flutter의 "내비게이션 및 라우팅" (0) | 2024.06.26 |
[Flutter] 6. Flutter의 "네트워킹 및 데이터 처리" (0) | 2024.06.26 |