flutter_liquid_glass_nav_bar 1.0.1
flutter_liquid_glass_nav_bar: ^1.0.1 copied to clipboard
A VisionOS-grade liquid glass and spring physics bottom navigation bar for Flutter with zero external dependencies.
Flutter Liquid Glass NavBar (液态毛玻璃物理弹簧导航栏) #
Flutter Liquid Glass NavBar 是一款工业设计级的 Flutter 底部悬浮导航栏组件。融合了 VisionOS 纯白高透立体水晶光学材质 与 Jelly Elastic 全套果冻弹性物理动力学,提供极致丝滑的触觉与视觉交互体验。
✨ 核心特性 (Key Features) #
- 💎 双层光学折射透镜 (Dual-Layer Optical Lens):外壳
15px高斯模糊 + 胶囊滑块10px高斯模糊,背景元素与轮廓优雅若隐若现; - 🌟 珠宝级晶体反光体系 (Jewelry-Grade Specular Optics):外壳与胶囊同时配备顶部阳光切线(
0.85纯白)与底部凝聚微晶反光弧(0.40纯白); - 🔮 Jelly Elastic 果冻动力学 (Jelly Spring Physics):Tab 切换过冲回弹,手指按压水滴升腾(
46px ➔ 64px自适应延伸)与 45° 动态镜面流光; - 📐 3D 三维立体纵深排版 (Spatial 3D Depth):按压滑块升腾时,被选中的图标平滑上浮
1.5px,文字微隐至0.78透明度,形成立体视觉落差; - 🎈 液态未读消息徽标 (Liquid Jelly Badge):
1.14x果冻呼吸跳跃与微拟物发丝边框,支持99+自动截断、小红点模式与完全自定义 Widget; - 🎨 完全解耦与多态图标 (Polymorphic Icons):原生纯 Flutter 零第三方依赖,原生支持
IconData、Widget(SVG/Lottie/Image)、本地图片路径与动态builder构造器; - ⚡ 120Hz 满帧渲染隔离 (GPU Repaint Isolation):底壳与滑块双层独立
RepaintBoundaryGPU 隔离,极度节约 CPU/GPU 开销; - 🌐 全端自适应与无障碍 (Multi-Platform & Accessibility):支持平板、iPad、折叠屏与桌面端
520px黄金约束居中,完整适配 iOS VoiceOver / Android TalkBack 与桌面端鼠标指针悬停。
📦 安装依赖 (Installation) #
在终端运行以下命令:
flutter pub add flutter_liquid_glass_nav_bar
或者在项目的 pubspec.yaml 中手动添加:
dependencies:
flutter_liquid_glass_nav_bar: ^1.0.0
导入头文件:
import 'package:flutter_liquid_glass_nav_bar/flutter_liquid_glass_nav_bar.dart';
🚀 快速上手 (Quick Start) #
基础用法 (使用 Flutter 原生 Material/Cupertino 图标) #
Important
最佳实践提示:在 Scaffold 中请务必开启 extendBody: true,并在列表底部留出适当的 padding(如 bottom: 100),以使页面内容滑动穿过底栏时呈现出最惊艳的高斯模糊折射与若隐若现透光效果。
import 'package:flutter/material.dart';
import 'package:flutter_liquid_glass_nav_bar/flutter_liquid_glass_nav_bar.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true, // 核心:使页面内容延伸至毛玻璃底栏背后
body: Center(
child: Text('当前选中的页面索引: $_currentIndex'),
),
bottomNavigationBar: LiquidGlassNavBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
items: const [
LiquidGlassNavBarItem(
icon: Icons.home_outlined,
activeIcon: Icons.home_rounded,
label: '首页',
),
LiquidGlassNavBarItem(
icon: Icons.explore_outlined,
activeIcon: Icons.explore_rounded,
label: '探索',
),
LiquidGlassNavBarItem(
icon: Icons.chat_bubble_outline_rounded,
activeIcon: Icons.chat_bubble_rounded,
label: '消息',
badgeCount: 3, // 未读消息数字徽标
),
LiquidGlassNavBarItem(
icon: Icons.person_outline_rounded,
activeIcon: Icons.person_rounded,
label: '我的',
),
],
),
);
}
}
🎨 多态图标使用指南 (Polymorphic Icons) #
LiquidGlassNavBarItem 原生支持多种类型的图标形式,满足各种复杂的业务与设计系统需求:
1. 原生 IconData (Material / Cupertino / 自定义 IconFont) #
LiquidGlassNavBarItem(
icon: Icons.home_outlined,
activeIcon: Icons.home_rounded, // 可选:选中时的激活态图标
label: '首页',
)
2. 任意自定义 Widget (SVG 矢量图 / Lottie 动效 / 图片) #
LiquidGlassNavBarItem(
icon: SvgPicture.asset('assets/icons/tab_home.svg'),
activeIcon: SvgPicture.asset('assets/icons/tab_home_active.svg'),
label: '首页',
)
3. 本地图片 Asset 路径 String #
LiquidGlassNavBarItem(
icon: 'assets/icons/home.png',
activeIcon: 'assets/icons/home_active.png',
label: '首页',
)
4. 动态构造器 builder: (context, isSelected) => Widget #
适用于使用第三方图标库(如 HeroIcons、PhosphorIcons)或需要自定义物理缩放动效的场景:
LiquidGlassNavBarItem(
builder: (context, isSelected) => AnimatedScale(
scale: isSelected ? 1.15 : 1.0,
duration: const Duration(milliseconds: 200),
child: Icon(
isSelected ? Icons.person_rounded : Icons.person_outline_rounded,
color: isSelected ? Theme.of(context).colorScheme.primary : const Color(0xFF5A606E),
),
),
label: '我的',
)
🎈 徽标与未读指示器 (Badges) #
1. 数字徽标 (自动支持 99+ 溢出与果冻弹性跳跃) #
LiquidGlassNavBarItem(
icon: Icons.notifications_none_rounded,
label: '通知',
badgeCount: 8, // 传入整数,大于 99 时自动截断展示 99+
)
2. 精致小红点 (Dot Badge) #
LiquidGlassNavBarItem(
icon: Icons.settings_outlined,
label: '设置',
showBadgeDot: true, // 显示发光小红点
)
3. 完全自定义徽标 (Custom Badge Widget) #
LiquidGlassNavBarItem(
icon: Icons.shopping_bag_outlined,
label: '商城',
customBadge: Container(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.white, width: 0.8),
),
child: const Text('HOT', style: TextStyle(fontSize: 8, fontWeight: FontWeight.bold, color: Colors.black)),
),
)
💎 全局主题扩展 (ThemeExtension Theming) #
推荐在 App 全局 ThemeData 中注入 LiquidGlassNavBarTheme,使整个项目的所有导航栏统一继承主题配置,同时在各页面仍然支持局部就近覆盖:
MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF6366F1)),
extensions: const [
LiquidGlassNavBarTheme(
height: 58.0,
floatingOffset: 14.0,
glassBlurSigma: 15.0,
glassOpacity: 0.30,
pillBlurSigma: 10.0,
pillOpacity: 0.50,
enableShimmer: true,
),
],
),
darkTheme: ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF818CF8),
brightness: Brightness.dark,
),
extensions: const [
LiquidGlassNavBarTheme(
height: 58.0,
floatingOffset: 14.0,
glassBlurSigma: 18.0,
glassOpacity: 0.22,
pillBlurSigma: 12.0,
pillOpacity: 0.40,
enableShimmer: true,
),
],
),
home: const MyHomePage(),
);
🛠️ 进阶定制与参数微调 (Advanced Customization) #
LiquidGlassNavBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
onReselect: (index) {
// 再次轻触当前已选中的 Tab 时触发 (如返回列表顶部或触发下拉刷新)
_scrollController.animateTo(0, duration: const Duration(milliseconds: 300), curve: Curves.easeOut);
},
// 1. 色彩与模式
selectedItemColor: const Color(0xFF6366F1),
unselectedItemColor: const Color(0xFF64748B),
backgroundColor: Colors.white,
pillColor: Colors.white,
badgeColor: Colors.redAccent,
isDark: false, // 显式指定深浅色,默认跟随 Theme.brightness
// 2. 光学材质调优
glassBlurSigma: 18.0, // 外壳高斯模糊 (默认 15.0)
glassOpacity: 0.28, // 外壳底色透明度 / 72% 透光率 (默认 0.30)
pillBlurSigma: 12.0, // 滑块内层高斯模糊 (默认 10.0)
pillOpacity: 0.55, // 滑块底色透明度 (默认 0.50)
enableShimmer: true, // 开启 45° 镜面反光流光扫描
// 3. 尺寸与几何布局
height: 60.0,
floatingOffset: 16.0,
maxWidth: 520.0, // 大屏/iPad/折叠屏自适应最大宽度
borderRadius: 30.0,
margin: const EdgeInsets.symmetric(horizontal: 20),
// 4. 物理动力学与动效
moveDuration: const Duration(milliseconds: 520),
pressDuration: const Duration(milliseconds: 420),
enableHaptics: true, // 开启 3 级物理触觉振动反馈
enableSpatialDepth: true, // 开启按压 1.5px 3D 纵深上浮
enableIconGlow: true, // 开启选中图标主题色悬浮微柔光
items: const [...],
)
📖 完整 API 属性速查表 (API Reference) #
1. LiquidGlassNavBar 参数表 #
| 属性分类 | 参数名 | 类型 | 默认值 | 详细说明 |
|---|---|---|---|---|
| 基础与状态 | items |
List<LiquidGlassNavBarItem> |
必填 | 导航项列表 (推荐 2~5 项) |
currentIndex |
int |
必填 | 当前激活项的索引 (0-based) | |
onTap |
ValueChanged<int> |
必填 | 点击或拖拽松手吸附时的回调 | |
onReselect |
ValueChanged<int>? |
null |
再次轻触当前已选中的 Tab 时触发 (可用于返回顶部/刷新) | |
| 色彩与主题 | selectedItemColor |
Color? |
Theme.primaryColor |
选中项的高亮品牌色 |
unselectedItemColor |
Color? |
0xFF5A606E / 0.72白 |
未选中项文字与图标的基础颜色 | |
backgroundColor |
Color? |
纯白 / surface |
底壳基底颜色 (深浅色模式自动适配高透纯白/表面色) | |
pillColor |
Color? |
纯白 |
胶囊滑块基底颜色 | |
badgeColor |
Color? |
Theme.errorColor |
消息未读小红点与数字徽标的背景色 | |
isDark |
bool? |
null (跟随系统) |
显式指定是否深色模式 (为 null 时自动响应主题) | |
| 光学与材质 | glassBlurSigma |
double? |
15.0 |
外壳高斯模糊度 (sigmaX & sigmaY) |
glassOpacity |
double? |
0.30 (70% 透光率) |
外壳纯白不透明度 | |
pillBlurSigma |
double? |
10.0 |
胶囊滑块内层高斯模糊度 (按压升腾时自动动态放大) | |
pillOpacity |
double? |
0.50 |
胶囊滑块静止态不透明度 | |
enableShimmer |
bool? |
true |
是否开启 45° 镜面流光微扫描动效 | |
| 尺寸与布局 | height |
double? |
58.0 |
导航栏主体高度 |
floatingOffset |
double? |
14.0 |
底部悬浮间距 (自动叠加系统安全区 padding) | |
maxWidth |
double? |
520.0 |
大屏/平板/折叠屏最大自适应宽度 (超出时居中悬浮) | |
margin |
EdgeInsetsGeometry? |
EdgeInsets.symmetric(horizontal: 18) |
导航栏外边距 | |
borderRadius |
double? |
29.0 |
外壳全圆角半径 | |
pillHeight |
double? |
46.0 |
胶囊滑块静止高度 (按压升腾时自动延伸至 pillHeight + 18) |
|
| 字体与排版 | selectedTextStyle |
TextStyle? |
w600, 10.5, letterSpacing: 0.1 |
选中项文本样式 (支持自定义字体、字号、字重) |
unselectedTextStyle |
TextStyle? |
w500, 10.5, letterSpacing: 0.1 |
未选中项文本样式 | |
iconSize |
double? |
22.0 |
图标标准渲染尺寸 | |
itemSpacing |
double? |
2.0 |
图标与文本之间的垂直间距 | |
| 物理与动效 | moveDuration |
Duration? |
520ms |
切 Tab 物理果冻回弹位移周期 |
pressDuration |
Duration? |
420ms |
手指按压升腾与释放周期 | |
enableHaptics |
bool? |
true |
是否开启 3 级物理触觉振动反馈 (HapticFeedback) |
|
enableSpatialDepth |
bool? |
true |
是否开启按压时图标 1.5px 3D 空间纵深上浮 |
|
enableIconGlow |
bool? |
true |
是否开启选中图标主题色悬浮微柔光 | |
moveCurve |
Curve? |
Cubic(0.175, 0.885, 0.32, 1.28) |
切 Tab 位移动画曲线 | |
pressCurve |
Curve? |
Curves.easeOutBack |
手指按压/释放形变曲线 |
2. LiquidGlassNavBarItem 参数表 #
| 参数名 | 类型 | 默认值 | 详细说明 |
|---|---|---|---|
label |
String |
必填 | 导航项标签文案 |
icon |
Object? |
null |
默认图标 (原生支持 IconData、Widget、本地图片 String) |
activeIcon |
Object? |
null |
选中状态下的高亮图标 (可选,类型同 icon) |
builder |
Widget Function(BuildContext, bool isSelected)? |
null |
自定义动态图标构造器 (最高优先级) |
badgeCount |
int? |
null |
未读消息数 (为 null 则不显示数字徽标,大于 99 自动显示 99+) |
showBadgeDot |
bool |
false |
是否显示未读小红点 (当 badgeCount 为 null 时生效) |
customBadge |
Widget? |
null |
自定义徽标组件 (若提供则优先使用此 Widget 替代默认气泡) |
❓ 常见问题 (FAQ) #
Q1: 为什么看不到毛玻璃模糊效果,底栏后面是纯白或纯黑? #
答:毛玻璃(BackdropFilter)需要底层有内容穿透才能产生高斯折射。请确保:
Scaffold(extendBody: true)已开启;- 页面背部有内容(如可滑动的
ListView、渐变背景图或卡片); - 列表底部添加了足够的内边距(如
padding: EdgeInsets.only(bottom: 100)),以便滑到底部时内容能在底栏背后透出。
Q2: 如何在 iPad、折叠屏或桌面 Web 端获得优雅的居中显示? #
答:组件默认内置了 maxWidth: 520.0 黄金排版约束。在大屏或宽屏设备上,导航栏会自动优雅居中悬浮,无需任何额外布局包裹。
📄 开源许可证 (License) #
本项目基于 MIT License 开源。欢迎提交 Issue 与 Pull Request 共同共建!