diff --git a/lib/core/custom_theme.dart b/lib/core/custom_theme.dart index a6c6376..3f15ad9 100644 --- a/lib/core/custom_theme.dart +++ b/lib/core/custom_theme.dart @@ -11,6 +11,8 @@ class CustomTheme { static Color onBoxColor = const Color(0xFF181818); static Color boxBorder = const Color(0xFF272727); static const Color textColor = Colors.white; + static Color navBarItemSelectedColor = primaryColor.withValues(green: 0.4); + static Color navBarItemUnselectedColor = Colors.white.withValues(alpha: 0.6); // ==================== Border Radius ==================== static const double standardBorderRadius = 12.0; diff --git a/lib/presentation/views/main_menu/custom_navigation_bar.dart b/lib/presentation/views/main_menu/custom_navigation_bar.dart index a8b18c8..15f15b6 100644 --- a/lib/presentation/views/main_menu/custom_navigation_bar.dart +++ b/lib/presentation/views/main_menu/custom_navigation_bar.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; @@ -70,50 +72,49 @@ class _CustomNavigationBarState extends State backgroundColor: CustomTheme.backgroundColor, body: tabs[currentIndex], extendBody: true, - bottomNavigationBar: SafeArea( - minimum: const EdgeInsets.only(bottom: 30), - child: Container( - margin: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(24), - color: CustomTheme.primaryColor, - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(24), - child: SizedBox( - height: 60, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - NavbarItem( - index: 0, - isSelected: currentIndex == 0, - icon: Icons.home_rounded, - label: loc.home, - onTabTapped: onTabTapped, - ), - NavbarItem( - index: 1, - isSelected: currentIndex == 1, - icon: Icons.gamepad_rounded, - label: loc.matches, - onTabTapped: onTabTapped, - ), - NavbarItem( - index: 2, - isSelected: currentIndex == 2, - icon: Icons.group_rounded, - label: loc.groups, - onTabTapped: onTabTapped, - ), - NavbarItem( - index: 3, - isSelected: currentIndex == 3, - icon: Icons.bar_chart_rounded, - label: loc.statistics, - onTabTapped: onTabTapped, - ), - ], + bottomNavigationBar: ClipRRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + decoration: BoxDecoration( + color: CustomTheme.boxColor.withValues(alpha: 0.8), + ), + child: SafeArea( + child: SizedBox( + height: 70, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + NavbarItem( + index: 0, + isSelected: currentIndex == 0, + icon: Icons.home_rounded, + label: loc.home, + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 1, + isSelected: currentIndex == 1, + icon: Icons.gamepad_rounded, + label: loc.matches, + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 2, + isSelected: currentIndex == 2, + icon: Icons.group_rounded, + label: loc.groups, + onTabTapped: onTabTapped, + ), + NavbarItem( + index: 3, + isSelected: currentIndex == 3, + icon: Icons.bar_chart_rounded, + label: loc.statistics, + onTabTapped: onTabTapped, + ), + ], + ), ), ), ), diff --git a/lib/presentation/widgets/navbar_item.dart b/lib/presentation/widgets/navbar_item.dart index 13a8d4d..6e2e24e 100644 --- a/lib/presentation/widgets/navbar_item.dart +++ b/lib/presentation/widgets/navbar_item.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; /// A navigation bar item widget that represents a single tab in a navigation bar. /// - [index]: The index of the tab. @@ -35,7 +36,45 @@ class NavbarItem extends StatefulWidget { State createState() => _NavbarItemState(); } -class _NavbarItemState extends State { +class _NavbarItemState extends State + with SingleTickerProviderStateMixin { + /// Animation controller for the scale animation + late AnimationController _animationController; + + /// Scale animation for the icon when selected + late Animation _scaleAnimation; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + + _scaleAnimation = Tween(begin: 1.0, end: 1.2).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOutBack, + ), + ); + + if (widget.isSelected) { + _animationController.forward(); + } + } + + // Retrigger animation on selection change + @override + void didUpdateWidget(NavbarItem oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.isSelected && !oldWidget.isSelected) { + _animationController.forward(); + } else if (!widget.isSelected && oldWidget.isSelected) { + _animationController.reverse(); + } + } + @override Widget build(BuildContext context) { return Expanded( @@ -48,19 +87,29 @@ class _NavbarItemState extends State { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - widget.icon, - color: widget.isSelected ? Colors.white : Colors.black, + ScaleTransition( + scale: widget.isSelected + ? _scaleAnimation + : const AlwaysStoppedAnimation(1.0), + child: Icon( + widget.icon, + color: widget.isSelected + ? CustomTheme.navBarItemSelectedColor + : CustomTheme.navBarItemUnselectedColor, + size: 26, + ), ), const SizedBox(height: 4), Text( widget.label, style: TextStyle( - color: widget.isSelected ? Colors.white : Colors.black, - fontSize: 12, + color: widget.isSelected + ? CustomTheme.navBarItemSelectedColor + : CustomTheme.navBarItemUnselectedColor, + fontSize: widget.isSelected ? 12 : 11, fontWeight: widget.isSelected ? FontWeight.bold - : FontWeight.normal, + : FontWeight.w500, ), ), ], @@ -69,4 +118,10 @@ class _NavbarItemState extends State { ), ); } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } } diff --git a/pubspec.yaml b/pubspec.yaml index e79ca17..74df2a5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.1+21 +version: 0.0.1+69 environment: sdk: ^3.8.1