Flutter의 애니메이션이 포함된 Pinterest 플로팅 탐색 모음

이 짧은 자습서에서는 사용자 스크롤 시 동작을 숨기고 다시 표시하여 Pinterest 앱의 탐색 표시줄을 만드는 방법을 배웁니다.

시작 설정은 다음과 같습니다.

Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return SizedBox(
            height: 260,
            child: Card(
              child: Center(child: Text('Item #$index')),
            ),
          );
        },
      ),
      bottomNavigationBar: SizedBox(
        height: 60,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Icon(Icons.home),
            Icon(Icons.search),
            Icon(Icons.favorite_border),
            Icon(Icons.person_rounded),
          ],
        ),
      ),
    );
  }


  • "ScrollUpdateNotification"유형의 NotificationListener<ScrollUpdateNotification>() 위젯에서 스캐폴드 위젯을 래핑합니다.
  • 이것은 사용자가 화면에서 스크롤을 시도할 때 실행되는 콜백 함수에서 "ScrollUpdateNotification"개체를 제공합니다.
  • 이제 Animated Container에 BottomNavigationBar를 래핑하고 다음과 같이 transform: 속성을 지정합니다.

  •  AnimatedContainer(
              duration: Duration(milliseconds: 300),
            > transform: Matrix4.translationValues(0, yTransValue,0),
              child: BottomNavBarWidget(),
            ),
    


  • 적절한 이름(yTransValue)을 사용하여 "double"유형의 변수를 만들고 값을 0으로 설정합니다
  • .
  • onNotification callBack이 스크롤 델타의 부호 값을 확인합니다.
    값이 1이면 사용자가 화면을 위로 스와이프했음을 의미하고 -1이면 사용자가 화면을 아래로 스와이프했음을 의미합니다.

  • onNotification: (notification) {
            if (notification.scrollDelta.sign == 1) {
              setState(() {
                yTransValue = 100;
              });
            } else if (notification.scrollDelta.sign == -1) {
              setState(() {
                yTransValue = 0;
              });
            }
          },
    


    그리고 우리는 끝났습니다.

    전체 코드는 다음과 같습니다.




    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      double yTransValue = 0;
    
      @override
      Widget build(BuildContext context) {
        return NotificationListener<ScrollUpdateNotification>(
          onNotification: (notification) {
            print(notification.metrics.axisDirection);
            print(notification.metrics.axis);
    
            if (notification.scrollDelta.sign == 1) {
              setState(() {
                yTransValue = 100;
              });
            } else if (notification.scrollDelta.sign == -1) {
              setState(() {
                yTransValue = 0;
              });
            }
          },
          child: Scaffold(
            body: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return SizedBox(
                  height: 260,
                  child: Card(
                    child: Center(child: Text('Item #$index')),
                  ),
                );
              },
            ),
            bottomNavigationBar: AnimatedContainer(
              duration: Duration(milliseconds: 300),
              transform: Matrix4.translationValues(0, yTransValue, 0),
              child: SizedBox(
                height: 60,
                child: Card(
                  color: Colors.grey,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      Icon(Icons.home),
                      Icon(Icons.search),
                      Icon(Icons.favorite_border),
                      Icon(Icons.person_rounded),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    


    코드 결과video

    좋은 웹페이지 즐겨찾기