// ignore_for_file: deprecated_member_use import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; class DidvanBNB extends StatelessWidget { final int currentTabIndex; final void Function(int index) onTabChanged; const DidvanBNB( {Key? key, required this.currentTabIndex, required this.onTabChanged}) : super(key: key); @override Widget build(BuildContext context) { return Container( height: 72, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: const BorderRadius.vertical(top: Radius.circular(0)), border: const Border( top: BorderSide( color: Color.fromARGB(255, 224, 224, 224), width: 1.5, ), ), ), padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ _NavBarItem( isSelected: currentTabIndex == 1, title: 'رسانه', selectedIconPath: 'lib/assets/icons/media selected.svg', // Selected SVG icon unselectedIconPath: 'lib/assets/icons/media.svg', // Unselected SVG icon onTap: () => onTabChanged(1), ), _NavBarItem( isSelected: currentTabIndex == 4, title: 'هوشان', selectedIconPath: 'lib/assets/icons/houshan_selected.svg', // Selected SVG icon unselectedIconPath: 'lib/assets/icons/bot.svg', // Unselected SVG icon onTap: () => onTabChanged(4), ), _NavBarItem( isSelected: currentTabIndex == 0, title: 'خانه', selectedIconPath: DesignConfig.isDark ? 'lib/assets/icons/selected home.svg' : 'lib/assets/icons/selected home.svg', unselectedIconPath: DesignConfig.isDark ? 'lib/assets/icons/home2.svg' : 'lib/assets/icons/home2.svg', // Unselected SVG icon onTap: () => onTabChanged(0), ), _NavBarItem( isSelected: currentTabIndex == 2, title: 'نبض صنعت', selectedIconPath: DesignConfig.isDark ? 'lib/assets/icons/Nabz_Sanat.svg' : 'lib/assets/icons/Nabz_Sanat.svg', // Selected SVG icon unselectedIconPath: DesignConfig.isDark ? 'lib/assets/icons/chart 2.svg' : 'lib/assets/icons/chart 2.svg', // Unselected SVG icon onTap: () => onTabChanged(2), ), _NavBarItem( isSelected: currentTabIndex == 3, title: 'کاوش', selectedIconPath: 'lib/assets/icons/explore select.svg', // Selected SVG icon unselectedIconPath: 'lib/assets/icons/discover.svg', // Unselected SVG icon onTap: () => onTabChanged(3), ), ], ), ); } } class _NavBarItem extends StatefulWidget { final VoidCallback onTap; final bool isSelected; final String title; final String selectedIconPath; final String unselectedIconPath; final bool isHomeButton; const _NavBarItem({ Key? key, required this.isSelected, required this.title, required this.selectedIconPath, required this.unselectedIconPath, required this.onTap, // ignore: unused_element_parameter this.isHomeButton = false, }) : super(key: key); @override State<_NavBarItem> createState() => _NavBarItemState(); } class _NavBarItemState extends State<_NavBarItem> with TickerProviderStateMixin { late AnimationController _scaleController; late AnimationController _bounceController; late AnimationController _rippleController; late Animation _scaleAnimation; late Animation _bounceAnimation; late Animation _rippleAnimation; bool _isPressed = false; @override void initState() { super.initState(); _scaleController = AnimationController( duration: const Duration(milliseconds: 150), vsync: this, ); _bounceController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); _rippleController = AnimationController( duration: const Duration(milliseconds: 400), vsync: this, ); _scaleAnimation = Tween( begin: 1.0, end: 0.85, ).animate(CurvedAnimation( parent: _scaleController, curve: Curves.easeInOut, )); _bounceAnimation = Tween( begin: 1.0, end: 1.2, ).animate(CurvedAnimation( parent: _bounceController, curve: Curves.elasticOut, )); _rippleAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _rippleController, curve: Curves.easeOut, )); } @override void dispose() { _scaleController.dispose(); _bounceController.dispose(); _rippleController.dispose(); super.dispose(); } void _onTapDown() { setState(() { _isPressed = true; }); _scaleController.forward(); _rippleController.forward(); } void _onTapUp() { setState(() { _isPressed = false; }); _scaleController.reverse(); _rippleController.reverse(); if (widget.isSelected) { _bounceController.forward().then((_) { _bounceController.reverse(); }); } widget.onTap(); } void _onTapCancel() { setState(() { _isPressed = false; }); _scaleController.reverse(); _rippleController.reverse(); } @override Widget build(BuildContext context) { return Expanded( child: Tooltip( message: widget.title, decoration: BoxDecoration( color: Theme.of(context).colorScheme.title, borderRadius: DesignConfig.highBorderRadius, boxShadow: DesignConfig.defaultShadow, ), child: GestureDetector( onTapDown: (_) => _onTapDown(), onTapUp: (_) => _onTapUp(), onTapCancel: _onTapCancel, child: Container( color: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ AnimatedBuilder( animation: _rippleAnimation, builder: (context, child) { return Container( width: 60 * _rippleAnimation.value, height: 60 * _rippleAnimation.value, decoration: BoxDecoration( shape: BoxShape.circle, color: Theme.of(context).colorScheme.primary.withOpacity( 0.1 * (1 - _rippleAnimation.value), ), ), ); }, ), Column( children: [ const SizedBox(height: 4), AnimatedBuilder( animation: Listenable.merge([_scaleAnimation, _bounceAnimation]), builder: (context, child) { final scale = _scaleAnimation.value * (widget.isSelected ? _bounceAnimation.value : 1.0); return Transform.scale( scale: scale, child: AnimatedContainer( padding: EdgeInsets.all(widget.isHomeButton ? 8 : 4), duration: DesignConfig.lowAnimationDuration, decoration: BoxDecoration( shape: BoxShape.circle, color: widget.isSelected ? Theme.of(context) .colorScheme .primary .withOpacity(0.1) : Colors.transparent, boxShadow: widget.isSelected ? [ BoxShadow( color: Theme.of(context) .colorScheme .primary .withOpacity(0.3), blurRadius: 8, spreadRadius: 1, ) ] : null, ), child: SizedBox( width: widget.isHomeButton ? 50 : (widget.isSelected ? 50 : 32), height: widget.isHomeButton ? 50 : (widget.isSelected ? 50 : 32), child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), transitionBuilder: (child, animation) { return ScaleTransition( scale: animation, child: RotationTransition( turns: Tween(begin: 0.8, end: 1.0) .animate(animation), child: child, ), ); }, child: SvgPicture.asset( widget.isSelected ? widget.selectedIconPath : widget.unselectedIconPath, key: ValueKey(widget.isSelected), ), ), ), ), ); }, ), AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: (!widget.isHomeButton && !widget.isSelected) ? AnimatedOpacity( opacity: _isPressed ? 0.6 : 1.0, duration: const Duration(milliseconds: 150), child: DidvanText( widget.title, style: Theme.of(context) .textTheme .bodySmall ?.copyWith(fontSize: 11), color: Theme.of(context).colorScheme.caption, fontWeight: FontWeight.w500, ), ) : const SizedBox.shrink(), ), const Spacer(), ], ), ], ), ), ), ), ); } }