위 사진처럼 사용자에게 사용방법을 알려주거나 알림 및 정보를 공지하는 화면을 AnimatedCrossFade 위젯과 제스쳐 탐지를 통해 구현할 수 있다.
먼저 화면에 보일 화면 두 가지를 AnimatedCrossFade의 firstChild, secondChild에 설정한다. 그리고 애니메이션의 기간인 duration과 화면에 나타낼 crossFadeState를 임의로 설정한다.
AnimatedCrossFade(
duration: Duration(milliseconds: 500),
firstChild: Padding(
padding: EdgeInsets.symmetric(
// ...
secondChild: Padding(
padding: EdgeInsets.symmetric(
// ...
crossFadeState: CrossFadeState.showFirst,
)
https://github.com/soaringwave/tiktokclone/commit/fee1d10660d0ec35d8defcbfae4650c953cbf6ce
이때 debug 모드로 crossFadeState를 변경해서 저장하면 애니메이션이 적용된 채로 화면이 fade되는 것을 확인할 수 있다.
그다음으로 사용자의 swipe를 감지해 화면 간 fade될 수 있도록 GestureDetector로 scaffold를 wrap한다.
return GestureDetector(
onPanUpdate: _onPanUpdate,
child: const Scaffold(
body: SafeArea(
child: AnimatedCrossFade(
// ...
GestureDetector가 사용자의 swipe를 감지할 수 있도록 onPanUpdate를 설정한다. 이때 _direction
변수를 만들어 사용자의 swipe 방향에 맞추어 변수가 변경되도록 설정한다. onPanUpdate 함수의 경우 DragUpdateDetails를 매개변수로 전달받는다. 이 정보를 통해 사용자가 어떤 방향으로 swipe했는지 확인할 수 있다.
enum Directions { right, left }
// ...
Directions _direction = Directions.right;
void _onPanUpdate(DragUpdateDetails details) {
print(details);
if (details.delta.dx > 0) {
setState(() {
_direction = Directions.right;
});
} else {
_direction = Directions.left;
}
}
onPanUpdate property
https://api.flutter.dev/flutter/widgets/GestureDetector/onPanUpdate.html
https://github.com/soaringwave/tiktokclone/commit/2764d9770dfd222aba64267045d7378e0ff49b6f
사용자의 제스쳐 swipe가 끝나면 제스쳐에 따라 화면에 보일 child를 설정해야 한다. 우선 화면에 보일 페이지를 _showingPage
변수에 임의로 firstChild로 설정한다.
enum Pages { first, second }
// ...
Pages _showingPage = Pages.first;
그리고 사용자의 swipe의 방향이 설정되고 swipe가 끝나면 그에 따라 보일 child를 설정하는_onPanEnd
를 설정한다.
void _onPanEnd(DragEndDetails details) {
if (_direction == Directions.left) {
setState(() {
_showingPage = Pages.second;
});
} else {
setState(() {
_showingPage = Pages.first;
});
}
}
// ...
return GestureDetector(
onPanUpdate: _onPanUpdate,
onPanEnd: _onPanEnd,
// ...
onPanEnd property
https://api.flutter.dev/flutter/widgets/GestureDetector/onPanEnd.html
_page
에 따라 화면에 특정 child가 보이도록 AnimatedCrossFade의 crossFadeState를 설정한다. 이렇게 하면 state의 변화에 따라 화면에 설정한 애니메이션과 함께 child의 전환이 이뤄진다.
// ...
child: AnimatedCrossFade(
// ...
crossFadeState: _showingPage == Pages.first
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
// ...
https://github.com/soaringwave/tiktokclone/commit/4c74d8c73ff22ed5b51c2845ac094ce4f426904f
https://github.com/soaringwave/tiktokclone/commit/04d3b68502df1f60a1742a82a6d8e722d7f2a7e7
AnimatedCrossFade class
https://api.flutter.dev/flutter/widgets/AnimatedCrossFade-class.html
화면 아래 버튼은 AnimatedContainer를 통해 설정했다.
https://github.com/soaringwave/tiktokclone/commit/e8a821cd42e681ffea1b6dfafc07e38e499069a8