draggable_floating_fab 0.1.3 copy "draggable_floating_fab: ^0.1.3" to clipboard
draggable_floating_fab: ^0.1.3 copied to clipboard

A draggable, sticky FAB overlay with a drag-to-dismiss zone for Flutter apps.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:draggable_floating_fab/draggable_floating_fab.dart';

void main() {
  runApp(const ExampleApp());
}

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

  @override
  State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
  String _currentPath = HomeScreen.routeName;

  late final _PathObserver _pathObserver = _PathObserver((String path) {
    if (_currentPath == path) {
      return;
    }
    setState(() => _currentPath = path);
  });

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Draggable Floating FAB Demo',
      navigatorKey: _navigatorKey,
      navigatorObservers: <NavigatorObserver>[_pathObserver],
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF143087)),
        useMaterial3: true,
      ),
      initialRoute: HomeScreen.routeName,
      routes: <String, WidgetBuilder>{
        HomeScreen.routeName: (_) => const HomeScreen(),
        HiddenScreen.routeName: (_) => const HiddenScreen(),
        SupportScreen.routeName: (_) => const SupportScreen(),
      },
      builder: (BuildContext context, Widget? child) {
        return DraggableSupportFabOverlay(
          onFabTap: () {
            _navigatorKey.currentState?.pushNamed(SupportScreen.routeName);
          },
          currentPath: () => _currentPath,
          hiddenRoutePaths: const <String>{
            HiddenScreen.routeName,
            SupportScreen.routeName,
          },
          fabColor: const Color(0xFF143087),
          bottomSafeInset: 16,
          child: child ?? const SizedBox.shrink(),
        );
      },
    );
  }
}

class _PathObserver extends NavigatorObserver {
  _PathObserver(this.onPath);

  final ValueChanged<String> onPath;

  void _emit(Route<dynamic>? route) {
    onPath(route?.settings.name ?? HomeScreen.routeName);
  }

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    _emit(route);
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    _emit(previousRoute);
  }

  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    _emit(newRoute);
  }
}

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

  static const String routeName = '/';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            const Text('Drag the support FAB, or tap it.'),
            const SizedBox(height: 16),
            FilledButton(
              onPressed: () {
                Navigator.of(context).pushNamed(HiddenScreen.routeName);
              },
              child: const Text('Open hidden route'),
            ),
          ],
        ),
      ),
    );
  }
}

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

  static const String routeName = '/hidden';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Hidden route')),
      body: const Center(child: Text('FAB is hidden on this route.')),
    );
  }
}

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

  static const String routeName = '/support';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Support')),
      body: const Center(child: Text('Opened from the floating FAB.')),
    );
  }
}
3
likes
155
points
224
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A draggable, sticky FAB overlay with a drag-to-dismiss zone for Flutter apps.

Repository (GitHub)
View/report issues

Topics

#flutter #fab #floating-action-button #overlay #ui

License

MIT (license)

Dependencies

flutter, shared_preferences

More

Packages that depend on draggable_floating_fab