Files
daily_mobileapp_customer/lib/widgets/tenantcategory.dart
2026-05-26 18:01:57 +05:30

117 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:nearledaily/constants/color_constants.dart';
import '../modules/tenant/category.dart';
class CategoryHeaderDelegate extends SliverPersistentHeaderDelegate {
final List<Category> categories;
final int selectedIndex;
final Function(int) onTap;
CategoryHeaderDelegate({
required this.categories,
required this.selectedIndex,
required this.onTap,
});
@override
double get minExtent => 90;
@override
double get maxExtent => 90;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final screenWidth = MediaQuery.of(context).size.width;
return Container(
color: Colors.white,
child: ListView.builder(
scrollDirection: Axis.horizontal,
physics: const BouncingScrollPhysics(),
itemCount: categories.length,
itemBuilder: (context, index) {
final item = categories[index];
// 🔥 Responsive width (5 items visible)
final itemWidth = screenWidth / 5;
final isSelected = selectedIndex == index;
return GestureDetector(
onTap: () => onTap(index),
child: SizedBox(
width: itemWidth,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 🔵 Icon Container
AnimatedContainer(
duration: const Duration(milliseconds: 250),
height: 55,
width: 55,
decoration: BoxDecoration(
color: isSelected
? Colors.transparent
: Colors.transparent,
// borderRadius: BorderRadius.circular(14),
),
alignment: Alignment.center,
child: item.icon.isNotEmpty
? Image.network(
item.icon,
height: 50,
width: 50,
fit: BoxFit.contain,
errorBuilder: (_, __, ___) =>
const Icon(Icons.image, size: 40),
)
: const Icon(Icons.image, size: 40),
),
const SizedBox(height: 3),
// 🏷️ Text
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Text(
item.name,
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color:
isSelected ? Colors.black87 : Colors.grey.shade800,
),
),
),
const SizedBox(height: 3),
// 🔥 Bottom Indicator
AnimatedContainer(
duration: const Duration(milliseconds: 250),
height: 3,
width: isSelected ? 30 : 0,
decoration: BoxDecoration(
color: ColorConstants.primaryColor,
borderRadius: BorderRadius.circular(10),
),
),
],
),
),
);
},
),
);
}
@override
bool shouldRebuild(covariant CategoryHeaderDelegate oldDelegate) {
return true; // required for GetX updates
}
}