liquid_glass_lens_navbar
A floating Liquid Glass bottom navigation bar for Flutter, modelled on the iOS 26 tab bar.
| Light | Liquid lens | Dark |
|---|---|---|
![]() |
![]() |
![]() |
- Frosted, saturated glass floating above your content, with light refraction along its rim.
- The selection lifts into a liquid glass lens while it moves or is dragged — it magnifies and refracts what is behind it, with chromatic fringing (fragment shader on Impeller).
- Drag along the bar to scrub between tabs, with haptic ticks.
- Hides on scroll, or collapses into a circle like iOS 26.
- Clear / Tinted / Solid glass, adjustable opacity, light and dark styles.
- Follows iOS Reduce Transparency, Increase Contrast and Reduce Motion.
- Adaptive quality: steps the effect down automatically on slow GPUs.
- Pure Flutter, no platform views. Tested on iOS and Android.
Install
flutter pub add liquid_glass_lens_navbar
Requires Flutter 3.35 or newer.
Usage
Scaffold(
extendBody: true, // let content scroll under the glass
body: ...,
bottomNavigationBar: LiquidGlassNavBar(
currentIndex: _index,
onTap: (i) => setState(() => _index = i),
items: const [
LiquidGlassNavItem(icon: Icons.article_outlined, selectedIcon: Icons.article, label: 'Today'),
LiquidGlassNavItem(icon: Icons.rocket_outlined, selectedIcon: Icons.rocket, label: 'Games'),
LiquidGlassNavItem(icon: Icons.layers_outlined, selectedIcon: Icons.layers, label: 'Apps'),
LiquidGlassNavItem(icon: Icons.search, label: 'Search'),
],
),
)
Hide on scroll
Scrolling down slides the whole bar off screen; scrolling up or reaching the top brings it back. Set minimizeStyle: LiquidGlassMinimizeStyle.circle to instead collapse it into a circle showing the selected tab (iOS 26 tabBarMinimizeBehavior), which expands when tapped.
final _tabBar = LiquidGlassNavBarController(); // dispose() it with the State
Scaffold(
extendBody: true,
body: LiquidGlassScrollMinimizer(
controller: _tabBar,
child: ListView(...),
),
bottomNavigationBar: LiquidGlassNavBar(
controller: _tabBar,
...
),
)
You can also drive it yourself with _tabBar.minimize() / _tabBar.expand().
Transparency & system settings
LiquidGlassNavBar(
appearance: LiquidGlassAppearance.tinted, // clear (default) | tinted | solid
backgroundOpacity: 0.4, // 0 = see-through … 1 = opaque
...
)
With respectSystemSettings: true (default) the bar follows iOS settings live:
| iOS setting | Effect |
|---|---|
| Accessibility › Display & Text Size › Reduce Transparency | solid bar, no blur, no lens (read via the bundled iOS plugin) |
| Accessibility › Display & Text Size › Increase Contrast | near-opaque glass with a visible border |
| Accessibility › Motion › Reduce Motion | no liquid lens / stretch |
iOS 26.1's Display & Brightness › Liquid Glass Clear / Tinted choice has no public API for apps to read, so expose appearance as an in-app setting if you want to offer it.
Options
| Parameter | Default | |
|---|---|---|
style |
from theme brightness | LiquidGlassStyle.light / .dark / copyWith(...) |
height |
62 |
bar height |
margin |
horizontal: 20 |
outer margin; bottom safe area is handled |
enableDrag |
true |
finger scrubbing |
enableLens |
true |
liquid lens while moving |
enableHaptics |
true |
selection haptics |
duration |
460ms |
move animation |
controller |
null |
LiquidGlassNavBarController for the minimized state |
minimizedSize |
50 |
diameter of the minimized circle |
appearance |
clear |
clear / tinted / solid |
backgroundOpacity |
null |
overrides the tint alpha (0..1) |
respectSystemSettings |
true |
follow Reduce Transparency / Increase Contrast / Reduce Motion |
minimizeStyle |
hide |
hide (slide off screen) / circle |
enableEdgeRefraction |
true |
bend the backdrop along the bar's rim (Impeller) |
LiquidGlassLens is exported too, so you can reuse the refracting glass lens elsewhere.
Performance
Backdrop blur is the expensive part of glass, and some GPUs (Android emulators, older OpenGL ES devices) render it very slowly. By default quality: LiquidGlassQuality.adaptive measures real raster times while the bar animates and steps down if frames are missed — usually within the first second:
| Level | Renders |
|---|---|
high |
blur + rim refraction + liquid lens shader |
medium |
blur only; the lens is a plain bright capsule |
low |
no backdrop effects — a near-opaque frosted fill |
The level never goes back up within a session. Force a level with quality: LiquidGlassQuality.high (or medium / low). LiquidGlassPerformance.instance.level exposes the current adaptive level.
Measured with example/lib/main_perf.dart (16 automatic tab switches, profile mode):
| Device | Raster p50 / p90 |
|---|---|
iPhone 18 Pro simulator (high) |
1.9 / 2.3 ms |
| Android emulator, Impeller GLES, before | 1366 / 2598 ms |
Android emulator, adaptive (ends at low) |
31 / 43 ms — the emulator alone needs ~28 ms for this page without any tab bar |
Platforms
| Glass + blur | Liquid lens & rim refraction | Reduce Transparency | |
|---|---|---|---|
| iOS (Impeller/Metal) | ✓ | ✓ | ✓ (native plugin) |
| Android, Impeller (Vulkan or OpenGLES) | ✓ | ✓ | – (no such setting) |
| Android on Skia (older devices, Impeller off) | ✓ | bright glass capsule instead | – |
| Web / desktop | untested | bright glass capsule expected (no shader filters) | – |
On Android the bar sits above the gesture-navigation handle (iOS lets it overlap the home-indicator area). Android's Remove animations setting maps to the Reduce Motion behaviour.
Example
cd example && flutter run
Libraries
- A Liquid Glass bottom tab bar for Flutter, inspired by iOS 26's floating glass tab bar (as seen in the App Store).


