Bar
GlassBar is a floating glass capsule for navigation: a title bar, a bottom bar or a now-playing pill, with black or white labels picked for legibility.
GlassBar · kGlassCapsule · Source
GlassBar is one glass surface with padding around its child. It is the navigation layer of an
iOS 26 style screen: the top bar with a back button and a title, a floating bottom bar, a
"now playing" pill over a feed.
The bar picks the text and icon colour of everything inside it, black or white, whichever reads best on the glass over what is behind it. Its items are ordinary widgets, not glass, so a bar full of icons and text still costs one surface.
When to use
- Navigation chrome that floats over content: titles, back and search actions, a mini player.
- A small pill that names the current screen or state.
- Not for content panels: use a Card instead (same body, a corner instead of a capsule).
- Not as a row of glass buttons. Every
GlassButtoninside a bar is one more surface. Use plain icons, or a toolbar (GlassButtonGroup), which draws many actions as one surface.
Usage
Stack(
children: <Widget>[
Positioned.fill(child: content), // what the glass refracts
const Positioned(
top: 16,
left: 16,
right: 16,
child: GlassBar(child: Center(child: Text('Library'))),
),
],
)
The bar sizes itself to its child. To stretch it across the screen, give it a width with
Positioned(left:, right:), a SizedBox or an Expanded.
Layout
borderRadiusdefaults tokGlassCapsule, a full pill whatever the height. Pass aBorderRadiusfor a rounded rectangle.paddingdefaults to 16 across and 8 down. Icon buttons usually want less, so their 44 px tap targets reach the edge of the glass.- No
SafeAreais applied for you. AddMediaQuery.paddingOf(context)to your offsets.
Labels
Text and icons inside the bar get the label colour through DefaultTextStyle and IconTheme.
Widgets that hard-code their own colour (for example Material's IconButton, which uses the colour
scheme) ignore it, so pass IconTheme.of(context).color to them, or use plain Icons in a
GestureDetector. The choice of colour is only as good as what the host knows about the backdrop:
see Legibility.
Warning
A bar is not refracted by glass that is its sibling. If glass cards scroll under a bar, wrap the bar
in GlassAbove, or use a scroll edge instead.
Code
import 'package:flutter/material.dart';
import 'package:g1455/g1455.dart';
/// A library screen: a top bar and a "now playing" bar over a list.
/// Assumes a GlassHost above the navigator (MaterialApp.builder).
class LibraryScreen extends StatelessWidget {
const LibraryScreen({super.key});
@override
Widget build(BuildContext context) {
final EdgeInsets safe = MediaQuery.paddingOf(context);
return Scaffold(
body: Stack(
children: <Widget>[
ListView.builder(
padding: EdgeInsets.fromLTRB(16, safe.top + 72, 16, safe.bottom + 96),
itemCount: 30,
itemBuilder: (BuildContext context, int i) =>
ListTile(leading: const Icon(Icons.album), title: Text('Album ${i + 1}')),
),
Positioned(
top: safe.top + 8,
left: 16,
right: 16,
child: const GlassBar(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
child: Row(
children: <Widget>[
Icon(Icons.arrow_back_ios_new),
Expanded(child: Text('Library', textAlign: TextAlign.center)),
Icon(Icons.search),
],
),
),
),
Positioned(
left: 16,
right: 16,
bottom: safe.bottom + 16,
child: const GlassBar(
padding: EdgeInsets.fromLTRB(16, 12, 16, 12),
child: Row(
children: <Widget>[
Icon(Icons.music_note),
SizedBox(width: 12),
Expanded(child: Text('Heat Waves', maxLines: 1, overflow: TextOverflow.ellipsis)),
Icon(Icons.pause),
SizedBox(width: 16),
Icon(Icons.fast_forward),
],
),
),
),
],
),
);
}
}API
| Parameter | Type | Default | Description |
|---|---|---|---|
child |
Widget |
required | The bar's items. They are content, not glass, and get the bar's label colour. |
borderRadius |
BorderRadius |
kGlassCapsule |
Corner radii. The default is a pill at any height. |
padding |
EdgeInsets |
EdgeInsets.symmetric(horizontal: 16, vertical: 8) |
Space between the glass edge and the items. |
finish |
GlassFinish? |
null |
The material. Null takes the theme's (normally the host's). |
key |
Key? |
null |