Implemented new nav bar
This commit is contained in:
@@ -27,6 +27,9 @@ class CustomTheme {
|
|||||||
/// Text color used throughout the app
|
/// Text color used throughout the app
|
||||||
static const Color textColor = Color(0xFFFFFFFF);
|
static const Color textColor = Color(0xFFFFFFFF);
|
||||||
|
|
||||||
|
/// Background color for the navigation bar
|
||||||
|
static const Color navBarBackgroundColor = Color(0xFF131313);
|
||||||
|
|
||||||
/// Selected color for the [NavbarItem]
|
/// Selected color for the [NavbarItem]
|
||||||
static Color navBarItemSelectedColor = primaryColor.withGreen(100);
|
static Color navBarItemSelectedColor = primaryColor.withGreen(100);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tallee/core/adaptive_page_route.dart';
|
import 'package:tallee/core/adaptive_page_route.dart';
|
||||||
import 'package:tallee/core/custom_theme.dart';
|
import 'package:tallee/core/custom_theme.dart';
|
||||||
@@ -75,103 +73,62 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
|||||||
backgroundColor: CustomTheme.backgroundColor,
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
body: tabs[currentIndex],
|
body: tabs[currentIndex],
|
||||||
extendBody: true,
|
extendBody: true,
|
||||||
bottomNavigationBar: SizedBox(
|
bottomNavigationBar: Container(
|
||||||
height: 70 + MediaQuery.of(context).padding.bottom,
|
height: 115,
|
||||||
child: Stack(
|
decoration: BoxDecoration(
|
||||||
children: [
|
color: CustomTheme.navBarBackgroundColor,
|
||||||
// Dynamically generated blur layers for ultra-smooth transition
|
border: Border.all(
|
||||||
...List.generate(34, (index) {
|
strokeAlign: BorderSide.strokeAlignOutside,
|
||||||
// Use cubic curve for an even more natural, smoother transition
|
color: CustomTheme.boxBorder,
|
||||||
final progress = index / 34.0; // 0.0 to 1.0
|
width: 2,
|
||||||
final cubic = progress * progress * progress; // cubic curve
|
),
|
||||||
final blurStrength =
|
borderRadius: const BorderRadius.only(
|
||||||
0.5 + (cubic * 50.0); // Very smooth from 0.5 to 50.5
|
topLeft: Radius.circular(30),
|
||||||
|
topRight: Radius.circular(30),
|
||||||
// Height goes completely from 100% to 0% (all the way down)
|
),
|
||||||
// With extra density at the bottom for softer transition
|
boxShadow: [
|
||||||
final heightFactor = index < 25
|
BoxShadow(
|
||||||
// First 25 layers: 100% to 30%
|
color: Colors.black.withValues(alpha: 0.1),
|
||||||
? 1.0 - (progress * 0.7)
|
blurRadius: 20,
|
||||||
// Last 10 layers: 30% to 0% (denser)
|
offset: const Offset(0, -5),
|
||||||
: 0.3 - ((index - 25) / 34.0);
|
|
||||||
|
|
||||||
return Positioned(
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
height:
|
|
||||||
(70 + MediaQuery.of(context).padding.bottom) *
|
|
||||||
heightFactor.clamp(0.05, 1.0),
|
|
||||||
child: ClipRect(
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: blurStrength,
|
|
||||||
sigmaY: blurStrength,
|
|
||||||
),
|
|
||||||
child: Container(color: Colors.transparent),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
// Gradient overlay
|
|
||||||
Positioned.fill(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.bottomCenter,
|
|
||||||
end: Alignment.topCenter,
|
|
||||||
colors: [
|
|
||||||
CustomTheme.boxColor.withValues(alpha: 1),
|
|
||||||
CustomTheme.boxColor.withValues(alpha: 0.5),
|
|
||||||
CustomTheme.boxColor.withValues(alpha: 0.2),
|
|
||||||
CustomTheme.boxColor.withValues(alpha: 0.0),
|
|
||||||
],
|
|
||||||
stops: const [0.0, 0.4, 0.8, 1],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Navbar content
|
|
||||||
SafeArea(
|
|
||||||
child: SizedBox(
|
|
||||||
height: 70,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
||||||
children: <Widget>[
|
|
||||||
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,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: <Widget>[
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,16 +87,27 @@ class _NavbarItemState extends State<NavbarItem>
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
ScaleTransition(
|
AnimatedContainer(
|
||||||
scale: widget.isSelected
|
width: 50,
|
||||||
? _scaleAnimation
|
height: 50,
|
||||||
: const AlwaysStoppedAnimation(1.0),
|
decoration: BoxDecoration(
|
||||||
child: Icon(
|
|
||||||
widget.icon,
|
|
||||||
color: widget.isSelected
|
color: widget.isSelected
|
||||||
? CustomTheme.navBarItemSelectedColor
|
? CustomTheme.primaryColor.withAlpha(50)
|
||||||
: CustomTheme.navBarItemUnselectedColor,
|
: Colors.transparent,
|
||||||
size: 32,
|
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||||
|
),
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
child: ScaleTransition(
|
||||||
|
scale: widget.isSelected
|
||||||
|
? _scaleAnimation
|
||||||
|
: const AlwaysStoppedAnimation(1.0),
|
||||||
|
child: Icon(
|
||||||
|
widget.icon,
|
||||||
|
color: widget.isSelected
|
||||||
|
? CustomTheme.navBarItemSelectedColor
|
||||||
|
: CustomTheme.navBarItemUnselectedColor,
|
||||||
|
size: 32,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
|||||||
Reference in New Issue
Block a user