liquid_glass_ios_widgets 0.3.1 copy "liquid_glass_ios_widgets: ^0.3.1" to clipboard
liquid_glass_ios_widgets: ^0.3.1 copied to clipboard

PlatformiOS

Native iOS 26 Liquid Glass components (buttons, switch, slider, segmented control, glass container, tab bar) as Flutter widgets via platform views.

example/lib/main.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:liquid_glass_ios_widgets/liquid_glass_ios_widgets.dart';

void main() => runApp(const ExampleApp());

/// The app's theme mode, switchable from the Controls tab. Native views
/// follow the Flutter theme, not the iOS appearance.
final themeMode = ValueNotifier(ThemeMode.system);

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: themeMode,
      builder: (context, mode, _) => MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData.light(),
        darkTheme: ThemeData.dark(),
        themeMode: mode,
        home: const GalleryPage(),
      ),
    );
  }
}

class GalleryPage extends StatefulWidget {
  const GalleryPage({super.key});

  @override
  State<GalleryPage> createState() => _GalleryPageState();
}

class _GalleryPageState extends State<GalleryPage> {
  int _tab = 0;

  @override
  Widget build(BuildContext context) {
    final bottomInset = MediaQuery.paddingOf(context).bottom;
    return Scaffold(
      body: Stack(
        children: [
          const Positioned.fill(child: _ColorfulBackground()),
          Positioned.fill(
            child: IndexedStack(
              index: _tab,
              children: [const _ControlsTab(), const _GlassTab()],
            ),
          ),
          Positioned(
            left: 0,
            right: 0,
            bottom: bottomInset,
            child: LiquidGlassTabBar(
              currentIndex: _tab,
              onTap: (index) => setState(() => _tab = index),
              items: const [
                LiquidGlassTabItem(
                  label: 'Controls',
                  systemImage: 'slider.horizontal.3',
                ),
                LiquidGlassTabItem(
                  label: 'Glass',
                  systemImage: 'drop',
                  selectedSystemImage: 'drop.fill',
                  badge: 'new',
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _ControlsTab extends StatefulWidget {
  const _ControlsTab();

  @override
  State<_ControlsTab> createState() => _ControlsTabState();
}

class _ControlsTabState extends State<_ControlsTab> {
  bool _switch = true;
  double _slider = 0.4;
  int _segment = 0;
  int _taps = 0;

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: EdgeInsets.fromLTRB(
        20,
        MediaQuery.paddingOf(context).top + 16,
        20,
        140,
      ),
      children: [
        const Text(
          'Liquid Glass',
          style: TextStyle(
            fontSize: 34,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
        Text(
          'isSupportLiquidGlass: ${LiquidGlass.isSupportLiquidGlass}',
          style: const TextStyle(color: Colors.white70),
        ),
        const SizedBox(height: 24),
        _Section(
          title: 'Theme mode',
          child: ValueListenableBuilder(
            valueListenable: themeMode,
            builder: (context, mode, _) => LiquidGlassSegmentedControl(
              selectedIndex: mode.index,
              onChanged: (index) => themeMode.value = ThemeMode.values[index],
              segments: const [
                LiquidGlassSegment(label: 'System'),
                LiquidGlassSegment(label: 'Light'),
                LiquidGlassSegment(label: 'Dark'),
              ],
            ),
          ),
        ),
        _Section(
          title: 'LiquidGlassAdaptive',
          child: LiquidGlassAdaptive(
            glass: LiquidGlassButton(
              label: 'Liquid Glass supported',
              systemImage: 'checkmark.seal.fill',
              onPressed: () => setState(() => _taps++),
            ),
            fallback: CupertinoButton.filled(
              onPressed: () => setState(() => _taps++),
              child: const Text('Fallback widget'),
            ),
          ),
        ),
        _Section(
          title: 'Buttons — tapped $_taps times',
          child: Wrap(
            spacing: 12,
            runSpacing: 12,
            crossAxisAlignment: WrapCrossAlignment.center,
            children: [
              LiquidGlassButton(
                label: 'Glass',
                onPressed: () => setState(() => _taps++),
              ),
              LiquidGlassButton(
                label: 'Prominent',
                style: LiquidGlassButtonStyle.prominent,
                onPressed: () => setState(() => _taps++),
              ),
              LiquidGlassButton(
                label: 'Share',
                systemImage: 'square.and.arrow.up',
                size: LiquidGlassControlSize.large,
                onPressed: () => setState(() => _taps++),
              ),
              LiquidGlassButton.icon(
                systemImage: 'heart.fill',
                foregroundColor: Colors.pink,
                onPressed: () => setState(() => _taps++),
              ),
              LiquidGlassButton.icon(
                systemImage: 'plus',
                style: LiquidGlassButtonStyle.prominent,
                tint: Colors.orange,
                onPressed: () => setState(() => _taps++),
              ),
              const LiquidGlassButton(label: 'Disabled', onPressed: null),
            ],
          ),
        ),
        _Section(
          title: 'Full width',
          child: LiquidGlassButton(
            label: 'Continue',
            style: LiquidGlassButtonStyle.prominent,
            tint: Colors.indigo,
            size: LiquidGlassControlSize.large,
            width: double.infinity,
            height: 52,
            onPressed: () => setState(() => _taps++),
          ),
        ),
        _Section(
          title: 'Switch — ${_switch ? 'on' : 'off'}',
          child: Row(
            children: [
              LiquidGlassSwitch(
                value: _switch,
                onChanged: (value) => setState(() => _switch = value),
              ),
              const SizedBox(width: 16),
              LiquidGlassSwitch(
                value: !_switch,
                activeColor: Colors.orange,
                onChanged: (value) => setState(() => _switch = !value),
              ),
            ],
          ),
        ),
        _Section(
          title: 'Slider — ${(_slider * 100).round()}%',
          child: LiquidGlassSlider(
            value: _slider,
            onChanged: (value) => setState(() => _slider = value),
          ),
        ),
        _Section(
          title: 'Segmented control — #$_segment',
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              LiquidGlassSegmentedControl(
                selectedIndex: _segment,
                onChanged: (index) => setState(() => _segment = index),
                segments: const [
                  LiquidGlassSegment(label: 'Day'),
                  LiquidGlassSegment(label: 'Week'),
                  LiquidGlassSegment(label: 'Month'),
                ],
              ),
              const SizedBox(height: 12),
              LiquidGlassSegmentedControl(
                expand: true,
                selectedIndex: _segment,
                onChanged: (index) => setState(() => _segment = index),
                segments: const [
                  LiquidGlassSegment(systemImage: 'list.bullet'),
                  LiquidGlassSegment(systemImage: 'square.grid.2x2'),
                  LiquidGlassSegment(systemImage: 'map'),
                ],
              ),
            ],
          ),
        ),
      ],
    );
  }
}

class _GlassTab extends StatelessWidget {
  const _GlassTab();

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: EdgeInsets.fromLTRB(
        20,
        MediaQuery.paddingOf(context).top + 16,
        20,
        140,
      ),
      children: [
        LiquidGlassContainer(
          padding: const EdgeInsets.all(20),
          shape: const LiquidGlassShape.rect(cornerRadius: 28),
          child: const Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Glass card',
                style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600),
              ),
              SizedBox(height: 8),
              Text(
                'A native .glassEffect() surface with Flutter content on top. '
                'Scroll to see the background refract through it.',
              ),
            ],
          ),
        ),
        const SizedBox(height: 20),
        Row(
          children: [
            Expanded(
              child: LiquidGlassContainer(
                height: 120,
                tint: Colors.blue.withValues(alpha: 0.4),
                shape: const LiquidGlassShape.rect(cornerRadius: 24),
                onTap: () {},
                child: const Center(child: Text('Tinted + interactive')),
              ),
            ),
            const SizedBox(width: 16),
            Expanded(
              child: LiquidGlassContainer(
                height: 120,
                variant: LiquidGlassVariant.clear,
                shape: const LiquidGlassShape.rect(cornerRadius: 24),
                child: const Center(
                  child: Text(
                    'Clear variant',
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
          ],
        ),
        const SizedBox(height: 20),
        Center(
          child: LiquidGlassContainer(
            shape: const LiquidGlassShape.capsule(),
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
            child: const Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(CupertinoIcons.music_note_2),
                SizedBox(width: 8),
                Text('Now playing — capsule'),
              ],
            ),
          ),
        ),
        const SizedBox(height: 20),
        for (final color in Colors.primaries)
          Container(
            height: 72,
            margin: const EdgeInsets.only(bottom: 12),
            decoration: BoxDecoration(
              color: color,
              borderRadius: BorderRadius.circular(20),
            ),
          ),
      ],
    );
  }
}

class _Section extends StatelessWidget {
  const _Section({required this.title, required this.child});

  final String title;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 28),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            title,
            style: const TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.w600,
            ),
          ),
          const SizedBox(height: 12),
          child,
        ],
      ),
    );
  }
}

class _ColorfulBackground extends StatelessWidget {
  const _ColorfulBackground();

  @override
  Widget build(BuildContext context) {
    return const DecoratedBox(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: [Color(0xFF1E3C72), Color(0xFF8E2DE2), Color(0xFFFF6A00)],
        ),
      ),
    );
  }
}
2
likes
160
points
576
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Native iOS 26 Liquid Glass components (buttons, switch, slider, segmented control, glass container, tab bar) as Flutter widgets via platform views.

Repository (GitHub)
View/report issues

Topics

#ios #liquid-glass #widget #cupertino #platform-views

License

MIT (license)

Dependencies

collection, flutter

More

Packages that depend on liquid_glass_ios_widgets

Packages that implement liquid_glass_ios_widgets