Files
wushu/lib/widgets/tap-liquid-glass.dart
Developer cba04235c8 release
2026-04-03 03:26:06 +08:00

215 lines
6.8 KiB
Dart

import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../constants/app_constants.dart';
import '../config/app_config.dart';
import '../services/get/theme_controller.dart';
import '../services/get/tap_liquid_glass_controller.dart';
class TapLiquidGlassNavigation extends StatelessWidget {
final int currentIndex;
final Function(int) onTap;
const TapLiquidGlassNavigation({
super.key,
required this.currentIndex,
required this.onTap,
});
@override
Widget build(BuildContext context) {
final themeController = Get.find<ThemeController>();
final glassController = Get.find<TapLiquidGlassController>();
return Obx(() {
final isDark = themeController.isDarkMode;
final enableBlur = themeController.enableBlurEffect;
final transparencyValues = glassController.transparencyValues;
return _buildGlassBar(context, isDark, enableBlur, transparencyValues);
});
}
Widget _buildGlassBar(
BuildContext context,
bool isDark,
bool enableBlur,
Map<String, double> transparencyValues,
) {
final backgroundOpacity = transparencyValues['backgroundOpacity']!;
return SafeArea(
top: false,
child: Container(
padding: EdgeInsets.only(
left: AppConfig.liquidGlassHorizontalMargin,
right: AppConfig.liquidGlassHorizontalMargin,
bottom: AppConfig.liquidGlassBottomMargin,
top: 8,
),
child: Container(
height: AppConfig.liquidGlassHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppConfig.liquidGlassCornerRadius,
),
boxShadow: backgroundOpacity > 0.2
? [
BoxShadow(
color: isDark
? Colors.black.withValues(alpha: 0.6)
: Colors.black.withValues(alpha: 0.15),
blurRadius: 35,
spreadRadius: -10,
offset: const Offset(0, 12),
),
]
: [],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(
AppConfig.liquidGlassCornerRadius,
),
child: enableBlur && backgroundOpacity >= 0.01
? BackdropFilter(
filter: ImageFilter.blur(
sigmaX: AppConfig.liquidGlassBlur,
sigmaY: AppConfig.liquidGlassBlur,
),
child: _buildGlassContent(isDark, backgroundOpacity),
)
: _buildGlassContent(isDark, backgroundOpacity),
),
),
),
);
}
Widget _buildGlassContent(bool isDark, double backgroundOpacity) {
return Stack(
children: [
if (backgroundOpacity >= 0.1)
Container(
decoration: BoxDecoration(
color: isDark
? Colors.black.withValues(alpha: backgroundOpacity * 0.4)
: Colors.white.withValues(alpha: backgroundOpacity),
borderRadius: BorderRadius.circular(
AppConfig.liquidGlassCornerRadius,
),
),
),
if (backgroundOpacity >= 0.15)
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppConfig.liquidGlassCornerRadius,
),
border: Border.all(
color: isDark
? Colors.white.withValues(alpha: backgroundOpacity * 0.2)
: Colors.black.withValues(alpha: backgroundOpacity * 0.1),
width: 0.6,
),
),
),
_buildNavItems(),
],
);
}
Widget _buildNavItems() {
final items = [
_NavItem(Icons.home_rounded, '🏠', '主页'),
_NavItem(Icons.explore_rounded, '🔍', '发现'),
_NavItem(Icons.favorite_border_rounded, '❤️', '收藏'),
_NavItem(Icons.person_outline_rounded, '👤', '个人'),
];
return Row(
children: List.generate(items.length, (index) {
return Expanded(
child: _buildNavItem(
items[index],
index == currentIndex,
() => onTap(index),
),
);
}),
);
}
Widget _buildNavItem(_NavItem item, bool isSelected, VoidCallback onTap) {
final themeController = Get.find<ThemeController>();
return Obx(() {
final isDark = themeController.isDarkMode;
final enableAnimation = themeController.enableAnimation;
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConfig.liquidGlassCornerRadius,
),
child: AnimatedContainer(
duration: enableAnimation
? const Duration(milliseconds: 250)
: Duration.zero,
curve: Curves.easeOutCubic,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
enableAnimation
? AnimatedScale(
scale: isSelected ? 1.1 : 1.0,
duration: const Duration(milliseconds: 200),
curve: Curves.easeOutCubic,
child: _buildIcon(item, isSelected, isDark),
)
: _buildIcon(item, isSelected, isDark),
const SizedBox(height: 3),
AnimatedDefaultTextStyle(
duration: enableAnimation
? const Duration(milliseconds: 200)
: Duration.zero,
style: TextStyle(
fontSize: 12,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
color: isSelected
? themeController.currentThemeColor
: (isDark ? Colors.grey[400] : Colors.grey[600]),
letterSpacing: 0.15,
),
child: Text(item.label),
),
],
),
),
),
);
});
}
Widget _buildIcon(_NavItem item, bool isSelected, bool isDark) {
final themeController = Get.find<ThemeController>();
return Icon(
item.icon,
size: 24,
color: isSelected
? themeController.currentThemeColor
: (isDark ? Colors.grey[400] : Colors.grey[600]),
);
}
}
class _NavItem {
final IconData icon;
final String emoji;
final String label;
_NavItem(this.icon, this.emoji, this.label);
}