반응형
이번 글의 목표는 아이콘이 천천히 나타난 뒤에 오른쪽으로 이동해주는 연속적인 애니메이션 구현하기 입니다.
1. 오른쪽으로 이동하는 AnimationController와 Animation을 추가로 선언해줍시다.
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with TickerProviderStateMixin {
late AnimationController _iconVisibleController;
late Animation<double> _iconVisibleAnimation;
//오른쪽으로 이동하는 AnimationController와 Animation 선언
late AnimationController _iconMoveRightController;
late Animation<double> _iconMoveRightAnimation;
@override
void initState() {
super.initState();
_iconVisibleController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_iconVisibleAnimation = Tween<double>(
begin: 0,
end: 1,
).animate(CurvedAnimation(
parent: _iconVisibleController,
curve: const Interval(0.0, 1.0, curve: Curves.easeIn),
));
_iconVisibleController.forward();
}
@override
void dispose() {
_iconVisibleController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: AnimatedBuilder(
animation: _iconVisibleAnimation,
builder: (context, child) => Opacity(
opacity: _iconVisibleAnimation.value,
child: Icon(
Icons.home,
size: 60,
color: Colors.black,
),
),
),
),
);
}
}
2. 선언했으니 선언한게 뭔지 정의해줘야겠죠?
2초동안 오른쪽으로 움직이게 합시다.
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with TickerProviderStateMixin {
late AnimationController _iconVisibleController;
late Animation<double> _iconVisibleAnimation;
late AnimationController _iconMoveRightController;
late Animation<double> _iconMoveRightAnimation;
@override
void initState() {
super.initState();
_iconVisibleController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_iconVisibleAnimation = Tween<double>(
begin: 0,
end: 1,
).animate(CurvedAnimation(
parent: _iconVisibleController,
curve: const Interval(0.0, 1.0, curve: Curves.easeIn),
));
//선언했으니 정의합시다.
_iconMoveRightController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_iconMoveRightAnimation = Tween<double>(
//현재 위치에서 시작해서 오른쪽으로 100px만큼 움직입니다.
begin: 0,
end: 100,
).animate(CurvedAnimation(
parent: _iconMoveRightController,
//시작은 어느정도 속도가 있는 상태로 시작
curve: const Interval(0.2, 1.0, curve: Curves.fastOutSlowIn),
));
_iconVisibleController.forward();
}
@override
void dispose() {
_iconVisibleController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: AnimatedBuilder(
animation: _iconVisibleAnimation,
builder: (context, child) => Opacity(
opacity: _iconVisibleAnimation.value,
child: Icon(
Icons.home,
size: 60,
color: Colors.black,
),
),
),
),
);
}
}
3. 이제 새로운 것을 추가해야 합니다. 여러 애니메이션을 순서대로 추가하려면 순서를 직접 지정해줘야 합니다.
그 순서는 addStatusListener로 지정해 줄 수 있어요.
처음 시작을 _iconVisibleController.forward()로 잡아줬죠?
그 밑에 만약 _iconVisibleController가 완료가 된 상태(Status)라면, 어떻게 할건지 지정해줍시다.
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with TickerProviderStateMixin {
late AnimationController _iconVisibleController;
late Animation<double> _iconVisibleAnimation;
late AnimationController _iconMoveRightController;
late Animation<double> _iconMoveRightAnimation;
@override
void initState() {
super.initState();
_iconVisibleController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_iconVisibleAnimation = Tween<double>(
begin: 0,
end: 1,
).animate(CurvedAnimation(
parent: _iconVisibleController,
curve: const Interval(0.0, 1.0, curve: Curves.easeIn),
));
_iconMoveRightController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_iconMoveRightAnimation = Tween<double>(
begin: 0,
end: 100,
).animate(CurvedAnimation(
parent: _iconMoveRightController,
curve: const Interval(0.2, 1.0, curve: Curves.fastOutSlowIn),
));
_iconVisibleController.forward();
//addStatusListener로 순서를 잡아줍시다.
//iconVisibleController로 첫 시작했으니 이녀석의 상태가 중요하겠죠?
_iconVisibleController.addStatusListener((status) {
//만약, _iconVisibleController의 상태가 completed라면
if (status == AnimationStatus.completed) {
// 저는 개인적으로 두번째 애니메이션이 시작하기 전 delay를 넣어보겠습니다.
Future.delayed(
const Duration(
seconds: 2,
),
);
// _iconMoveRightController를 실행합니다.
_iconMoveRightController.forward();
},
}
);
}
@override
void dispose() {
_iconVisibleController.dispose();
//잊지맙시다. dispose
_iconMoveRightController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: AnimatedBuilder(
animation: _iconVisibleAnimation,
builder: (context, child) => Opacity(
opacity: _iconVisibleAnimation.value,
child: Icon(
Icons.home,
size: 60,
color: Colors.black,
),
),
),
),
);
}
}
4. Controller, Animation 선언과 정의도 다했고, 순서도 지정해줬습니다.
그러면 어떤 대상이 어떤 애니메이션으로 실행될 지 지정해줍시다.
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget>
with TickerProviderStateMixin {
late AnimationController _iconVisibleController;
late Animation<double> _iconVisibleAnimation;
late AnimationController _iconMoveRightController;
late Animation<double> _iconMoveRightAnimation;
@override
void initState() {
super.initState();
_iconVisibleController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_iconVisibleAnimation = Tween<double>(
begin: 0,
end: 1,
).animate(CurvedAnimation(
parent: _iconVisibleController,
curve: const Interval(0.0, 1.0, curve: Curves.easeIn),
));
_iconMoveRightController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
_iconMoveRightAnimation = Tween<double>(
begin: 0,
end: 100,
).animate(CurvedAnimation(
parent: _iconMoveRightController,
curve: const Interval(0.2, 1.0, curve: Curves.fastOutSlowIn),
));
_iconVisibleController.forward();
_iconVisibleController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
Future.delayed(
const Duration(
seconds: 2,
),
);
_iconMoveRightController.forward();
}
}
);
}
@override
void dispose() {
_iconVisibleController.dispose();
_iconMoveRightController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: AnimatedBuilder(
animation: _iconVisibleAnimation,
builder: (context, child) => Opacity(
opacity: _iconVisibleAnimation.value,
// 두번째 애니메이션이 실행될 대상입니다.
child: AnimatedBuilder(
// 애니메이션은 iconMoveRightAnimation
animation: _iconMoveRightAnimation,
// 아까는 Opacity를 이용했지만 이번엔 위치를 옮기는 것이기 때문에 Transform.translate
builder: (context, child) => Transform.translate(
// Offset의 파라미터는 2개 필요. x값, y값
// 오른쪽으로만 움직일거니까 x에 값을 적어줍니다.
offset: Offset(_iconMoveRightAnimation.value, 0),
child: const Icon(
Icons.home,
size: 60,
color: Colors.black,
),
),
),
),
),
),
);
}
}
짠!
결과물입니다.
이제 다음 페이지에서는 아이콘이 천천히 나타난 뒤에 오른쪽으로 이동했으니,
이제 왼쪽으로 움직이는 애니메이션을 추가해보도록 하겠습니다.
원글 : https://blaan.cc/Flutter-Animation-3-2-831209c1e62348a3a07bfeb201ec7eda
반응형
'개발 > Flutter' 카테고리의 다른 글
[Flutter] Animation :: 5. 애니메이션 만들기 (Recap) (0) | 2023.04.21 |
---|---|
[Flutter] Animation :: 4. 애니메이션 만들기 (3) (0) | 2023.04.21 |
[Flutter] Animation :: 2. 애니메이션 만들기 (1) (0) | 2023.04.21 |
[Flutter] Animation :: 1. 개요 (0) | 2023.04.21 |