tiktokclone: tutorial screen 2 (AnimatedCrossFade, onPanUpdate, onPanEnd)

두그루·2023년 11월 30일
0


위 사진처럼 사용자에게 사용방법을 알려주거나 알림 및 정보를 공지하는 화면을 AnimatedCrossFade 위젯과 제스쳐 탐지를 통해 구현할 수 있다.

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되는 것을 확인할 수 있다.

onPanUpdate

그다음으로 사용자의 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

onPanEnd

사용자의 제스쳐 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


📎 강의
https://nomadcoders.co/tiktok-clone/lectures/4183

profile
계속 해보자

0개의 댓글