GlassSegmentedControl class

A glass morphism segmented control following Apple's design patterns.

GlassSegmentedControl provides a sophisticated segmented control with an animated glass indicator, jelly physics, and smooth transitions between segments. It matches iOS's UISegmentedControl appearance and behavior.

Key Features

  • Animated Glass Indicator: Smoothly animates between segments
  • Jelly Physics: Organic squash and stretch effects during movement
  • Drag Support: Swipe between segments with velocity-based snapping
  • Sharp Text: Selected text stays sharp above the glass
  • Flexible Sizing: Automatically sizes segments evenly
  • Customizable Appearance: Full control over colors, sizes, and effects

Performance Note

When placing inside glass containers (GlassCard, GlassPanel) with blur, use one of these approaches for best performance:

  • Set parent container to quality: GlassQuality.premium (no BackdropFilter)
  • Or set parent settings to blur: 0 (skips BackdropFilter)
  • Or place outside glass containers (like bottom bars)

Standard quality glass containers with blur may show minor flicker during indicator animations due to BackdropFilter recomposition.

Usage

Basic Usage

int selectedIndex = 0;

GlassSegmentedControl(
  segments: ['Daily', 'Weekly', 'Monthly'],
  selectedIndex: selectedIndex,
  onSegmentSelected: (index) {
    setState(() => selectedIndex = index);
  },
)

Within LiquidGlassLayer (Grouped Mode)

AdaptiveLiquidGlassLayer(
  settings: LiquidGlassSettings(
    thickness: 30,
    blur: 3,
    refractiveIndex: 1.59,
  ),
  child: Column(
    children: [
      GlassSegmentedControl(
        segments: ['One', 'Two', 'Three'],
        selectedIndex: _selectedIndex,
        onSegmentSelected: (index) {
          setState(() => _selectedIndex = index);
        },
      ),
    ],
  ),
)

Standalone Mode

GlassSegmentedControl(
  segments: ['Option A', 'Option B'],
  selectedIndex: _selectedIndex,
  onSegmentSelected: (index) {
    setState(() => _selectedIndex = index);
  },
  useOwnLayer: true,
  settings: LiquidGlassSettings(
    thickness: 30,
    blur: 3,
  ),
)

Custom Styling

GlassSegmentedControl(
  segments: ['Small', 'Medium', 'Large'],
  selectedIndex: _selectedIndex,
  onSegmentSelected: (index) {
    setState(() => _selectedIndex = index);
  },
  height: 36,
  borderRadius: 18,
  selectedTextStyle: TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w600,
    color: Colors.white,
  ),
  unselectedTextStyle: TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w500,
    color: Colors.white.withOpacity(0.6),
  ),
)
Inheritance

Constructors

GlassSegmentedControl({required List<String> segments, required int selectedIndex, required ValueChanged<int> onSegmentSelected, Key? key, double height = GlassDefaults.heightControl, double borderRadius = GlassDefaults.borderRadius, EdgeInsetsGeometry padding = const EdgeInsets.all(2), TextStyle? selectedTextStyle, TextStyle? unselectedTextStyle, Color? backgroundColor, Color? indicatorColor, LiquidGlassSettings? indicatorSettings, LiquidGlassSettings? glassSettings, bool useOwnLayer = false, GlassQuality quality = GlassQuality.standard, GlobalKey<State<StatefulWidget>>? backgroundKey})
Creates a glass segmented control.
const

Properties

backgroundColor Color?
Background color of the segmented control.
final
backgroundKey GlobalKey<State<StatefulWidget>>?
Optional background key for Skia/Web refraction.
final
borderRadius double
Border radius of the segmented control.
final
glassSettings LiquidGlassSettings?
Glass effect settings (only used when useOwnLayer is true).
final
hashCode int
The hash code for this object.
no setterinherited
height double
Height of the segmented control.
final
indicatorColor Color?
Color of the indicator when not being dragged.
final
indicatorSettings LiquidGlassSettings?
Glass settings for the draggable indicator.
final
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
onSegmentSelected ValueChanged<int>
Called when a segment is selected.
final
padding EdgeInsetsGeometry
Padding around the indicator inside the background.
final
quality GlassQuality
Rendering quality for the glass effect.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
segments List<String>
List of segment labels to display.
final
selectedIndex int
Index of the currently selected segment.
final
selectedTextStyle TextStyle?
Text style for the selected segment.
final
unselectedTextStyle TextStyle?
Text style for unselected segments.
final
useOwnLayer bool
Whether to create its own layer or use grouped glass.
final

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<GlassSegmentedControl>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited