일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Hello World
- Flutter Tutorial
- Column Widget
- 반석천
- Flutter Example
- Flutter 예제
- Flutter 강좌
- Flutter 앱 배포
- Scaffold
- Cached Image
- AppBar
- Image.network
- ListTile
- HTTP
- Snackbar
- listview
- sqlite
- FutureBuilder
- Row Widget
- navigator
- Row
- WillPopScope
- Networking
- CrossAxisAlignment
- ListView.builder
- MainAxisAlignment
- node.js
- InkWell
- Load Image
- flutter
- Today
- Total
꿈꾸는 시스템 디자이너
Flutter 강좌 - Animate a widget across screens | 스크린 간 애니메이션 효과 주기 본문
Flutter 강좌 - Animate a widget across screens | 스크린 간 애니메이션 효과 주기
독행소년 2019. 6. 28. 15:35
Flutter 강좌 목록 : https://here4you.tistory.com/120
이번 강좌에서는 스크린을 넘나드는 이미지 애니메이션에 대해서 알아본다. 예를 들어, 갤러리에 썸네일 이미지가 타잉형태로 존재하다가 특정 썸네일이 선택되면 해당 이미지가 크게 확대되는 앱을 사용해본 경험이 있을 것이다. 썸네일들을 출력하는 스크린에서 썸네일을 선택하여 새로운 스크린에서 해당 이미지를 크게 출력하고자 할때 스크린의 적재됨에도 마치 썸네일이 확대되어 큰 이미지로 변하는 애니메이션 효과를 만들 수 있다.
이런한 애니메이션 효과를 주기위해서 Hero라는 위젯을 이용한다. 두 개의 스크린이 존재할 때 각 스크린에 Hero 위젯을 추가하고 동일한 tag로 연결하며 두 스크린의 이동 중에 Hero 위젯에 등록된 자식 위젯은 사라지지 않고 애니메이션 처리할 수 있다.
소스코드는 다음과 같다.
import 'package:flutter/material.dart';
void main() => runApp(HeroApp());
class HeroApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Transition Demo',
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
// Hero 위젯이 onTap을 제공되지 않으므로 GestureDetector로 묶어서 기능 부여
body: GestureDetector(
// Hero 추가
child: Hero(
// Hero의 tag. 애니메이션될 Hero들은 동일 tag를 가져야함
tag: 'imageHero',
// Hero에 이미지 추가. 외부 이미지를 가져옴
child: Image.network('https://picsum.photos/250?image=9'),
),
// 탭되면 DetailScreen을 생성하여 적재
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return DetailScreen();
}));
},
),
);
}
}
class DetailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
// Hero 위젯이 onTap을 제공되지 않으므로 GestureDetector로 묶어서 기능 부여
body: GestureDetector(
child: Center(
child: Hero(
// Hero의 tag. 애니메이션될 Hero들은 동일 tag를 가져야함
tag: 'imageHero',
// Hero에 이미지 추가. 동일 이미지를 이용해서 한 이미지가 스크린을 넘나드는 애니메이션 효과 제공
child: Image.network('https://picsum.photos/250?image=9')),
),
// 탭하면 현재 스크린을 pop하여 제거
onTap: () {
Navigator.pop(context);
},
),
);
}
}
소스를 살펴보면, MainScreen과 DetailScreen 모두 Hero 위젯을 가지고 있으며, Hero의 child로 동일한 웹 이미지를 설정하고 있다. 그리고 tag도 동일하게 가지고 있다. Navigator를 이용해 스크린을 push하고 pop할 때 Hero 위젯으로 설장한 이미지는 사라지지 않고 이동하는 것 같은 애니메이션 효과가 발생한다.
두 스크린 모두 Hero를 GestureDetector로 묶은 이유는 Hero 위젯에서 사용자의 인터랙션을 처리하는 기능을 제공하고 있지 않기 때문에 Hero를 GestrueDetector로 래핑하여 onTap을 처리할 수 있도록 하기 위함이다.
실행화면은 다음과 같다.
위의 이미지에서는 단편적으로 표시되지만, MainScreen에 출력되던 노트북 이미지를 탭하면 DetailScreen 스크린이 적재되지만 노트북 이미지는 사라지지 않고 스무스하게 중앙으로 이동하게 된다. 다시 보트북 이미지를 탭하면 DetailScreen 스크린인 팝업되어 제거되고 MainScreen 스크린이 출력되는데 이 때에도 노트북 이미지는 사라지지 않고 스무르하게 이동한다.
본 강좌는 Flutter의 공식 사이트의 문서를 참고하여 작성되었습니다.
https://flutter.dev/docs/cookbook/navigation/hero-animations
Flutter Code Examples 강좌를 추천합니다.
- 제 블로그에서 Flutter Code Examples 프로젝트를 시작합니다.
- Flutter의 다양한 예제를 소스코드와 실행화면으로 제공합니다.
- 또한 모든 예제는 Flutter Code Examples 앱을 통해 테스트 가능합니다.
Flutter Code Examples 강좌로 메뉴로 이동