import 'package:flutter/material.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; /// 用来描述底部导航栏的每一项 class KRCustomBottomNavBarItem { /// 未选中时的图片名称 final String imageName; /// 选中时的图片名称(可选,不传则用同一张 imageName) final String? activeImageName; /// 标签(可选) final String? label; KRCustomBottomNavBarItem({ required this.imageName, this.activeImageName, this.label, }); } class KRCustomBottomNavBar extends StatelessWidget { /// 传入当前选中的索引 final int currentIndex; /// 导航栏的各个条目信息 final List items; /// 点击某项时的回调 final ValueChanged onTap; /// 背景色 final Color backgroundColor; /// 选中时 图标/文字 颜色 final Color selectedColor; /// 未选中时 图标/文字 颜色 final Color unselectedColor; /// 导航栏高度(不含安全区额外高度) final double height; /// 是否在内部自动使用 SafeArea final bool useSafeArea; const KRCustomBottomNavBar({ Key? key, required this.currentIndex, required this.items, required this.onTap, this.backgroundColor = Colors.white, this.selectedColor = Colors.blue, this.unselectedColor = Colors.grey, this.height = 56.0, this.useSafeArea = true, }) : super(key: key); @override Widget build(BuildContext context) { assert(items.isNotEmpty, 'The items list cannot be empty.'); assert(currentIndex >= 0 && currentIndex < items.length, 'The currentIndex must be within the bounds of the items list.'); Widget child = Container( color: backgroundColor, height: height, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: List.generate(items.length, (index) { final item = items[index]; final bool isSelected = (index == currentIndex); final iconName = isSelected ? (item.activeImageName ?? item.imageName) : item.imageName; final textColor = isSelected ? selectedColor : unselectedColor; return Expanded( child: InkWell( onTap: () => onTap(index), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ KrLocalImage( imageName: iconName, height: 24, width: 24, ), if (item.label != null) ...[ const SizedBox(height: 4), Text( item.label!, style: TextStyle(color: textColor, fontSize: 12), ), ], ], ), ), ); }), ), ); // 使用 SafeArea 包裹,避免底部被手势栏遮挡 return useSafeArea ? SafeArea(child: child) : child; } }