import 'package:flutter/material.dart'; import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart'; class SimpleBottomNavBar extends StatefulWidget { final int currentIndex; final Function(int) onTap; const SimpleBottomNavBar({ super.key, required this.currentIndex, required this.onTap, }); @override State createState() => _SimpleBottomNavBarState(); } class _SimpleBottomNavBarState extends State with TickerProviderStateMixin { late AnimationController _fabAnimationController; late AnimationController _borderRadiusAnimationController; late Animation fabAnimation; late Animation borderRadiusAnimation; late CurvedAnimation fabCurve; late CurvedAnimation borderRadiusCurve; late AnimationController _hideBottomBarAnimationController; final List _iconList = [ Icons.dashboard_rounded, Icons.favorite_rounded, Icons.wb_sunny_rounded, Icons.settings_rounded, ]; @override void initState() { super.initState(); _fabAnimationController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); _borderRadiusAnimationController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, ); fabCurve = CurvedAnimation( parent: _fabAnimationController, curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn), ); borderRadiusCurve = CurvedAnimation( parent: _borderRadiusAnimationController, curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn), ); fabAnimation = Tween(begin: 0, end: 1).animate(fabCurve); borderRadiusAnimation = Tween( begin: 0, end: 1, ).animate(borderRadiusCurve); _hideBottomBarAnimationController = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); Future.delayed( const Duration(milliseconds: 300), () => _fabAnimationController.forward(), ); Future.delayed( const Duration(milliseconds: 300), () => _borderRadiusAnimationController.forward(), ); } @override void dispose() { _fabAnimationController.dispose(); _borderRadiusAnimationController.dispose(); _hideBottomBarAnimationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBottomNavigationBar( icons: _iconList, activeIndex: widget.currentIndex, onTap: widget.onTap, backgroundColor: Colors.black, splashColor: Colors.pinkAccent.withValues(alpha: 0.3), activeColor: Colors.pinkAccent, inactiveColor: Colors.grey[400]!, notchAndCornersAnimation: borderRadiusAnimation, splashSpeedInMilliseconds: 300, notchSmoothness: NotchSmoothness.verySmoothEdge, gapLocation: GapLocation.center, gapWidth: 60, leftCornerRadius: 20, rightCornerRadius: 20, hideAnimationController: _hideBottomBarAnimationController, shadow: BoxShadow( offset: const Offset(0, -3), blurRadius: 15, spreadRadius: 1, color: Colors.black.withValues(alpha: 0.4), ), ); } } class SimpleFloatingActionButton extends StatefulWidget { final VoidCallback? onPressed; const SimpleFloatingActionButton({super.key, this.onPressed}); @override State createState() => _SimpleFloatingActionButtonState(); } class _SimpleFloatingActionButtonState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _scaleAnimation; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 200), vsync: this, ); _scaleAnimation = Tween(begin: 1.0, end: 0.95).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), ); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _animationController, builder: (context, child) { return Transform.scale( scale: _scaleAnimation.value, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( colors: [Colors.pinkAccent, Colors.purpleAccent], begin: Alignment.topLeft, end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( color: Colors.pinkAccent.withValues(alpha: 0.4), blurRadius: 12, spreadRadius: 2, offset: const Offset(0, 4), ), ], ), child: FloatingActionButton( onPressed: () { _animationController.forward().then((_) { _animationController.reverse(); }); widget.onPressed?.call(); }, backgroundColor: Colors.transparent, elevation: 0, child: const Icon( Icons.messenger_rounded, color: Colors.white, size: 28, ), ), ), ); }, ); } }