ABOUT ME

-

  • [ Flutter ] Animation Navigation Bar
    Application/Flutter 2024. 6. 30. 22:00
    반응형

    https://flutterawesome.com/flutter-animated-navigation-bar/

     

    Flutter Animated Navigation Bar

    Flutter Animated Navigation Bar

    flutterawesome.com

    일반적인 네비게이션 바 기능 보다는 애니메이션이 있는 네비게이션 바를 구현해보고 싶어서

    git 코드를 보며 기능을 구현해보았다.


    우선 navigation bar 파일을 만들어서 네비게이션을 구성

    git 코드를 보며 내 생각대로 조금 수정

    class BottomNavigation extends StatefulWidget {
      @override
      State<BottomNavigation> createState() => _BottomNavigation();
    }
    
    class _BottomNavigation extends State<BottomNavigation> {
      int selectBtn = 1;
      @override
      Widget build(BuildContext context) {
        return Container(
          child: navigationBar()
        );
      }
    
      AnimatedContainer navigationBar() {
        return AnimatedContainer(
          height: 70.0,
          duration: const Duration(milliseconds: 400),
          decoration: BoxDecoration(
            color: white,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20),
              topRight:
              Radius.circular(20),
            ),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              for (int i = 0; i < navBtn.length; i++)
                GestureDetector(
                  onTap: () => setState(() => selectBtn = i),
                  child: iconBtn(i),
                ),
            ],
          ),
        );
      }
    
      SizedBox iconBtn(int i) {
        bool isActive = selectBtn == i ? true : false;
        var height = isActive ? 60.0 : 0.0;
        var width = isActive ? 50.0 : 0.0;
        return SizedBox(
          width: 75.0,
          child: Stack(
            children: [
              Align(
                alignment: Alignment.topCenter,
                child: AnimatedContainer(
                  height: height,
                  width: width,
                  duration: const Duration(milliseconds: 200),
                  child: isActive
                      ? CustomPaint(
                    painter: ButtonNotch(),
                  )
                      : const SizedBox(),
                ),
              ),
              Align(
                alignment: Alignment.center,
                child: SvgPicture.asset(
                  navBtn[i].imagePath,
                  color: isActive ? mint : darkGrey,
                ),
              ),
            ],
          ),
        );
      }
    }

     

    Duration으로 애니메이션의 시간을 조절

     

    메뉴 아이콘을 관리하는 파일을 만들어 메뉴 아이콘 리스트를 만듬.

    SVG 파일을 사용하였기에 Flutter의 SvgPicture.asset을 이용하여 아이콘을 생성

    dependencies:
      flutter:
        sdk: flutter
      flutter_svg: ^1.0.0
      
      flutter:
        assets:
        - assets/icons/

    svg 파일을 이용할려면 flutter_svg 의존성을 추가해야한다.

    반응형
    class Model {
      final int id;
      final String imagePath;
      final String name;
    
      Model({
        required this.id,
        required this.imagePath,
        required this.name,
      });
    }
    
    List<Model> navBtn = [
      Model(id: 0, imagePath: 'assets/icons/calendar.svg', name: 'calendar'),
      Model(id: 1, imagePath: 'assets/icons/home.svg', name: 'home'),
      Model(id: 2, imagePath: 'assets/icons/user.svg', name: 'user'),
    ];

    https://www.svgrepo.com

     

    SVG Repo - Free SVG Vectors and Icons

    Free Vectors and Icons in SVG format. ✅ Download free mono or multi color vectors for commercial use. Search in 500.000+ Free SVG Vectors and Icons.

    www.svgrepo.com

    SVG 파일은 위 사이트를 이용해서 아이콘을 적용

     

    Custom Painter 파일은 아이콘을 눌렀을때 어떤 애니메이션을 적용할지 그려준다.

    class ButtonNotch extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        var dotPoint = Offset(size.width / 2, 2);
    
        var paint_1 = Paint()
          ..color = mint
          ..style = PaintingStyle.fill;
        var paint_2 = Paint()
          ..color = white
          ..style = PaintingStyle.fill;
    
        var path = Path();
    
        path.moveTo(0, 0);
        path.quadraticBezierTo(7.5, 0, 12, 5);
        path.quadraticBezierTo(size.width / 2, size.height / 3, size.width - 12, 5);
        path.quadraticBezierTo(size.width - 7.5, 0, size.width, 0);
        path.close();
        canvas.drawPath(path, paint_1);
        canvas.drawCircle(dotPoint, 5, paint_2);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return false;
      }
    }

    최종적으로 파일은 

    menu.dart : 메뉴 리스트를 가지고 있는 파일

    custom_paint.dart : 그림을 그려주는 파일

    bottom_navigation.dartt : 하단 네비게이션 파일

     

     

    마지막으로 화면 하단에 네비게이션을 적용

    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: SafeArea(
            child: Scaffold(
              backgroundColor: mint,
              // body: Home(),
                bottomNavigationBar: BottomNavigation()
              ),
            ),
          );
      }
    }

     

    그럼 이렇게 누른 탭에 애니메이션이 적용된다.

    728x90
    반응형