HydroNutrify_Ari_e41221567/lib/ui/shared/bottom_navbar.dart

147 lines
4.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:mobile_monitoring/core/constants/constants.dart';
class BottomNavbar extends StatelessWidget {
final int currentIndex;
final ValueChanged<int> onTap;
const BottomNavbar({
super.key,
required this.currentIndex,
required this.onTap,
});
// Warna hijau yang dicocokkan dengan desain
final Color activeGreen = AppColors.navbarActive;
Widget _buildNavItem(IconData icon, String label, int index) {
final isSelected = currentIndex == index;
return GestureDetector(
onTap: () => onTap(index),
behavior: HitTestBehavior.translucent,
child: SizedBox(
width: 70, // Memberikan area tap yang cukup
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: isSelected ? activeGreen : Colors.grey.shade400,
size: 28,
),
const SizedBox(height: 4),
Text(
label,
style: TextStyle(
color: isSelected ? activeGreen : Colors.grey.shade500,
fontSize: 12,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
),
),
],
),
),
);
}
Widget _buildHomeNavItem(int index) {
return GestureDetector(
onTap: () => onTap(index),
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: activeGreen, // Warna hijau solid sesuai gambar
// Shadow dihapus/diminimalisir karena di desain aslinya terlihat flat
),
child: const Icon(
Icons.home_rounded,
color: Colors.white,
size: 34,
),
),
);
}
@override
Widget build(BuildContext context) {
// Tinggi total navbar diperbesar sedikit untuk mengakomodasi notch & tombol melayang
return SizedBox(
height: 100,
child: Stack(
clipBehavior: Clip.none,
children: [
// Background dengan notch melengkung yang di-generate otomatis
Positioned.fill(
child: CustomPaint(
painter: _NavbarNotchPainter(),
),
),
// Menu Kiri dan Kanan
Positioned(
bottom: 0,
left: 0,
right: 0,
height: 65, // Tinggi area bar putihnya saja
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// Menggunakan icon bar_chart agar mirip dengan desain 3 tiang grafik
_buildNavItem(Icons.bar_chart_rounded, AppStrings.monitoring, 0),
const SizedBox(width: 80), // Ruang kosong untuk notch di tengah
_buildNavItem(Icons.show_chart_rounded, AppStrings.graph, 2),
],
),
),
// Home Button di tengah
Positioned(
top: 5, // Mengatur posisi tombol melayang pas di atas lengkungan
left: 0,
right: 0,
child: Center(
child: _buildHomeNavItem(1),
),
),
],
),
);
}
}
class _NavbarNotchPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// Menggunakan bawaan Flutter agar lekukan otomatis presisi dan tidak ada glitch visual/abu-abu
const notchShape = CircularNotchedRectangle();
// Titik awal y untuk background putih (y = 35)
// Area dari y=0 hingga y=35 akan murni transparan menembus background aplikasi
final backgroundRect = Rect.fromLTWH(0, 35, size.width, size.height - 35);
// Ukuran dan posisi lubang (notch)
final notchRect = Rect.fromCenter(
center: Offset(size.width / 2, 35),
width: 80, // Dibuat sedikit lebih besar dari tombol (60) agar ada spasi putihnya
height: 80,
);
// Dapatkan jalur (path) yang sudah dihitung otomatis
final path = notchShape.getOuterPath(backgroundRect, notchRect);
// Gambar bayangan (shadow) yang halus, tidak menghasilkan blok abu-abu gelap
canvas.drawShadow(path, Colors.black.withValues(alpha: 0.1), 8.0, false);
// Gambar background navbar putih
final paint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}