flutter_overlay_window_plus 1.0.0 copy "flutter_overlay_window_plus: ^1.0.0" to clipboard
flutter_overlay_window_plus: ^1.0.0 copied to clipboard

PlatformAndroid

A Flutter plugin for displaying overlay windows over other apps with enhanced features and better API.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_overlay_window_plus/flutter_overlay_window_plus.dart';
import 'dart:developer' as developer;
import 'dart:async';

import 'package:flutter_overlay_window_plus/src/overlay_enums.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Overlay Window Plus Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Overlay Window Plus Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _isOverlayActive = false;
  String _lastEvent = 'No events yet';
  Timer? _timer;
  int _counter = 0;

  @override
  void initState() {
    super.initState();
    _listenToOverlayEvents();
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  void _listenToOverlayEvents() {
    FlutterOverlayWindowPlus.overlayListener.listen((event) {
      setState(() {
        _lastEvent = 'Event: ${event['event']}';
        if (event['event'] == 'overlay_shown') {
          _isOverlayActive = true;
        } else if (event['event'] == 'overlay_closed') {
          _isOverlayActive = false;
        }
      });
      developer.log('Overlay event: $event');
    });
  }

  Future<void> _checkPermission() async {
    final hasPermission = await FlutterOverlayWindowPlus.isPermissionGranted();
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(hasPermission ? 'Permission granted' : 'Permission denied'),
          backgroundColor: hasPermission ? Colors.green : Colors.red,
        ),
      );
    }
  }

  Future<void> _requestPermission() async {
    final granted = await FlutterOverlayWindowPlus.requestPermission();
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(granted ? 'Permission granted' : 'Please grant permission manually'),
          backgroundColor: granted ? Colors.green : Colors.orange,
        ),
      );
    }
  }

  Future<void> _showOverlay() async {
    final success = await FlutterOverlayWindowPlus.showOverlay(
      height: 200,
      width: WindowSize.matchParent,
      alignment: OverlayAlignment.top,
      flag: OverlayFlag.defaultFlag,
      overlayTitle: "Demo Overlay",
      overlayContent: "This is a demo overlay window",
      enableDrag: true,
      positionGravity: PositionGravity.auto,
    );

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(success ? 'Overlay shown' : 'Failed to show overlay'),
          backgroundColor: success ? Colors.green : Colors.red,
        ),
      );
    }
  }

  Future<void> _showSmallOverlay() async {
    final success = await FlutterOverlayWindowPlus.showOverlay(
      height: 100,
      width: 150,
      alignment: OverlayAlignment.topRight,
      flag: OverlayFlag.defaultFlag,
      overlayTitle: "Small Overlay",
      overlayContent: "Small overlay in top-right",
      enableDrag: true,
      positionGravity: PositionGravity.right,
    );

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(success ? 'Small overlay shown' : 'Failed to show overlay'),
          backgroundColor: success ? Colors.green : Colors.red,
        ),
      );
    }
  }

  Future<void> _startStreaming() async {
    if (_isOverlayActive) {
      // Start the timer to send data every second
      _timer?.cancel(); // Cancel any existing timer
      _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
        setState(() {
          _counter++;
        });
        FlutterOverlayWindowPlus.shareData('Live text: $_counter');
      });
    } else {
      // Show overlay first, then start streaming
      final success = await FlutterOverlayWindowPlus.showOverlay(
        height: 200,
        width: WindowSize.matchParent,
        alignment: OverlayAlignment.top,
        overlayTitle: "Live Text Stream",
        overlayContent: "Waiting for stream to start...",
      );
      if (success) {
        _startStreaming(); // Call again to start the timer
      }
    }
  }

  void _stopStreaming() {
    _timer?.cancel();
    setState(() {
      _counter = 0;
    });
  }

  Future<void> _closeOverlay() async {
    final success = await FlutterOverlayWindowPlus.closeOverlay();
    if (success) {
      _stopStreaming(); // Stop streaming when overlay is closed
    }
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(success ? 'Overlay closed' : 'Failed to close overlay'),
          backgroundColor: success ? Colors.green : Colors.red,
        ),
      );
    }
  }

  Future<void> _shareData() async {
    final success = await FlutterOverlayWindowPlus.shareData('Hello from main app!');
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(success ? 'Data shared' : 'Failed to share data'),
          backgroundColor: success ? Colors.green : Colors.red,
        ),
      );
    }
  }

  Future<void> _getPosition() async {
    final position = await FlutterOverlayWindowPlus.getOverlayPosition();
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(position != null 
            ? 'Position: (${position.x}, ${position.y})' 
            : 'No overlay active'),
          backgroundColor: Colors.blue,
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              // Status card
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Status',
                        style: Theme.of(context).textTheme.headlineSmall,
                      ),
                      const SizedBox(height: 8),
                      Text('Overlay Active: $_isOverlayActive'),
                      Text('Last Event: $_lastEvent'),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 16),

              // Permission section
              Text(
                'Permissions',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _checkPermission,
                      child: const Text('Check Permission'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _requestPermission,
                      child: const Text('Request Permission'),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 16),

              // Overlay controls
              Text(
                'Overlay Controls',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
              const SizedBox(height: 8),
              ElevatedButton(
                onPressed: _isOverlayActive ? null : _showOverlay,
                child: const Text('Show Default Overlay'),
              ),
              const SizedBox(height: 8),
              ElevatedButton(
                onPressed: _isOverlayActive ? null : _showSmallOverlay,
                child: const Text('Show Small Overlay'),
              ),
              const SizedBox(height: 8),
              ElevatedButton(
                onPressed: _isOverlayActive ? _closeOverlay : null,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.red,
                  foregroundColor: Colors.white,
                ),
                child: const Text('Close Overlay'),
              ),
              const SizedBox(height: 16),

              // Streaming Section
              Text(
                'Text Streaming',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _timer == null || !_timer!.isActive
                          ? _startStreaming
                          : null,
                      child: const Text('Start Stream'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _timer != null && _timer!.isActive
                          ? _stopStreaming
                          : null,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.orange,
                      ),
                      child: const Text('Stop Stream'),
                    ),
                  ),
                ],
              ),
              if (_timer != null && _timer!.isActive)
                Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Text('Streaming count: $_counter', textAlign: TextAlign.center),
                ),

              const SizedBox(height: 16),

              // Communication
              Text(
                'Communication',
                style: Theme.of(context).textTheme.headlineSmall,
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _isOverlayActive ? _shareData : null,
                      child: const Text('Share Data'),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: ElevatedButton(
                      onPressed: _isOverlayActive ? _getPosition : null,
                      child: const Text('Get Position'),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}
3
likes
150
points
95
downloads

Publisher

verified publisherjbergloda.site

Weekly Downloads

A Flutter plugin for displaying overlay windows over other apps with enhanced features and better API.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_overlay_window_plus

Packages that implement flutter_overlay_window_plus