일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 서비스 vs 쓰레드
- Rxjava Observable
- 자바 다형성
- ar vr 차이
- 클래스
- 안드로이드 유닛테스트란
- 안드로이드 레트로핏 사용법
- 스택 큐 차이
- ANR이란
- android ar 개발
- rxjava disposable
- 멤버변수
- 안드로이드 라이선스 종류
- 스택 자바 코드
- 2022 플러터 안드로이드 스튜디오
- android retrofit login
- 플러터 설치 2022
- 큐 자바 코드
- jvm 작동 원리
- 안드로이드 유닛 테스트
- 2022 플러터 설치
- jvm이란
- 안드로이드 유닛 테스트 예시
- 안드로이드 os 구조
- 안드로이드 라이선스
- 객체
- 안드로이드 레트로핏 crud
- rxjava cold observable
- rxjava hot observable
- 서비스 쓰레드 차이
- Today
- Total
나만을 위한 블로그
[Flutter] Hero 애니메이션 사용법 본문
Hero 애니메이션은 안드로이드에서 공유 요소 전환과 같은 효과를 내는 애니메이션이다.
Hero 애니메이션의 공식문서부터 먼저 확인한다.
https://docs.flutter.dev/ui/animations/hero-animations
한 화면에서 다른 화면으로 이미지를 이동하는 걸 Hero 애니메이션이라 하며 공유 요소 전환이라고도 한다. Hero 위젯을 써서 쉽게 구현할 수 있고 MaterialPageRoute를 써서 새 경로를 지정하면 머티리얼 디자인 모션 사양에 설명된 대로 이미지가 곡선 경로를 따라 날아간다
아래는 플러터 문서에서 링크된 깃허브로 이동하면 볼 수 있는 코드다.
class PhotoHero extends StatelessWidget {
const PhotoHero({
super.key,
required this.photo,
this.onTap,
required this.width,
});
final String photo;
final VoidCallback? onTap;
final double width;
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
child: Hero(
tag: photo,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Image.asset(
photo,
fit: BoxFit.contain,
),
),
),
),
);
}
}
이 코드의 핵심 정보는 아래와 같다.
- 시작 경로는 Hero 애니메이션이 앱의 home 프로퍼티로 제공될 때 MaterialApp에 의해 암시적으로 push된다
- InkWell이 이미지를 감싸서 onTap 제스처를 쉽게 추가할 수 있다
- 머티리얼 위젯을 투명한 색으로 정의하면 이미지가 목적지로 날아갈 때 배경에서 튀어나오게 할 수 있다
- SizedBox는 애니메이션 시작, 끝에서 Hero 위젯 크기를 지정한다
- 이미지의 맞춤 속성을 BoxFit.contain으로 설정하면 화면 비율을 바꾸지 않고 전환하는 동안 이미지가 최대한 커진다
아래는 HeroAnimation 클래스의 전체 코드다.
class HeroAnimation extends StatelessWidget {
const HeroAnimation({super.key});
Widget build(BuildContext context) {
timeDilation = 5.0; // 1.0 means normal animation speed.
return Scaffold(
appBar: AppBar(
title: const Text('Basic Hero Animation'),
),
body: Center(
child: PhotoHero(
photo: 'images/flippers-alpha.png',
width: 300.0,
onTap: () {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flippers Page'),
),
body: Container(
color: Colors.lightBlueAccent,
padding: const EdgeInsets.all(16),
alignment: Alignment.topLeft,
child: PhotoHero(
photo: 'images/flippers-alpha.png',
width: 100.0,
onTap: () {
Navigator.of(context).pop();
},
),
),
);
}
));
},
),
),
);
}
}
이 코드의 핵심은 아래와 같다.
- 유저가 Hero가 포함된 InkWell을 탭하면 MaterialPageRoute를 써서 목적지 경로를 생성한다. 이 경로를 네비게이터의 스택으로 push하면 Hero 애니메이션이 트리거된다
- Container는 대상 경로의 왼쪽 상단 모서리, AppBar 아래에 PhotoHero를 배치한다
- 목적지 PhotoHero의 onTap은 네비게이터 스택을 팝업해서 Hero를 원래 경로로 되돌리는 애니메이션을 트리거한다
- 디버깅하는 동안 전환 속도를 늦추려면 timeDilation 프로퍼티를 사용한다
위 코드를 실행하면 아래처럼 작동한다.
PhotoHero 클래스는 Hero의 크기, 이미지, onTap에 정의한 동작을 유지하는데 아래와 같은 위젯 트리를 빌드한다.
정리하면 Hero 애니메이션은 한 화면에서 다른 화면으로 이동할 때 같이 날아가는 것처럼 보이게 만들어주는 애니메이션이다. 구현하려면 Hero 위젯을 사용하며 애니메이션을 트리거하기 위해 InkWell을 사용할 수 있다. InkWell이 아니라도 GestureDetector를 써서 onTap 매개변수를 구현하면 동일한 효과를 낼 수 있다.
그리고 Hero 애니메이션을 구현할 때 아래를 신경써야 한다.
- 두 화면에서 각각 Hero 위젯을 사용해야 한다
- Hero 위젯을 사용하면 tag는 필수 구현대상이다
- Navigator 기반 화면 전환(push, pop 등)
PhotoHero의 build()에서 Hero 위젯의 첫 번째 매개변수로 tag를 적고 photo를 넣은 걸 볼 수 있다.
그리고 HeroAnimation 클래스에서 Center, Container 안에서 각각 PhotoHero 위젯을 구현하고 push, pop을 통해 앞으로 / 뒤로 화면을 이동할 때마다 Hero 애니메이션을 보여준다.
적절하게 넣으면 단조로운 화면 이동 과정을 색다르게 보여줄 수 있을 것이다.
'Flutter' 카테고리의 다른 글
[Flutter] GlobalKey란? 유효성 검사 예시 (0) | 2024.10.20 |
---|---|
[Flutter] BottomSheet 사용법 (0) | 2024.09.21 |
[Flutter] GridView란? GridView 사용법 (0) | 2024.08.22 |
[Flutter] Optional Positional Parameters, Named Parameters란? (0) | 2024.08.20 |
[Flutter] 스와이프해서 지우기 구현하는 법(Dismissible) (0) | 2024.08.19 |