log_overlay 0.0.1
log_overlay: ^0.0.1 copied to clipboard
Lightweight debug console overlay for Flutter. View print() logs in a draggable floating button with zero configuration. Perfect for quick debugging.
import 'package:flutter/material.dart';
import 'package:log_overlay/log_overlay.dart';
void main() {
LogOverlay.init(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Log Overlay Showcase',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
brightness: Brightness.light,
),
useMaterial3: true,
cardTheme: CardThemeData(
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
builder: LogOverlay.builder(),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _logInfo() {
print('[INFO] Information message - Everything is working correctly!');
}
void _logWarning() {
print('[WARNING] Warning message - Please check this potential issue.');
}
void _logError() {
print('[ERROR] Error message - Something went wrong!');
}
void _logDebug() {
print('[DEBUG] Debug message - Developer information for troubleshooting.');
}
Future<void> _simulateWorkflow() async {
print('[WORKFLOW] Starting user authentication workflow...');
await Future.delayed(const Duration(milliseconds: 500));
print('[WORKFLOW] Step 1: Validating credentials...');
await Future.delayed(const Duration(milliseconds: 600));
print('[WORKFLOW] Step 2: Checking permissions...');
await Future.delayed(const Duration(milliseconds: 400));
print('[WORKFLOW] Step 3: Loading user profile...');
await Future.delayed(const Duration(milliseconds: 500));
print('[WORKFLOW] ✓ Authentication successful!');
}
void _generateMultipleLogs() {
print('[BATCH] Starting batch log generation...');
for (int i = 1; i <= 10; i++) {
print('[BATCH] Generating log entry $i of 10');
}
print('[BATCH] ✓ Batch generation complete!');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
title: const Text('Log Overlay Showcase'),
centerTitle: true,
elevation: 0,
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.deepPurple,
Colors.deepPurple.shade50,
Colors.blue.shade50,
],
),
),
child: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_buildSectionCard(
title: 'Generate Logs',
icon: Icons.article_outlined,
iconColor: Colors.deepPurple,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_buildLogButton(
label: 'Log Info Message',
icon: Icons.info_outline,
color: Colors.blue,
onPressed: _logInfo,
),
const SizedBox(height: 12),
_buildLogButton(
label: 'Log Warning',
icon: Icons.warning_amber_outlined,
color: Colors.orange,
onPressed: _logWarning,
),
const SizedBox(height: 12),
_buildLogButton(
label: 'Log Error',
icon: Icons.error_outline,
color: Colors.red,
onPressed: _logError,
),
const SizedBox(height: 12),
_buildLogButton(
label: 'Log Debug Message',
icon: Icons.bug_report_outlined,
color: Colors.purple,
onPressed: _logDebug,
),
const SizedBox(height: 20),
Divider(color: Colors.grey.shade300),
const SizedBox(height: 12),
_buildAdvancedButton(
label: 'Simulate Workflow',
icon: Icons.psychology_outlined,
gradient: LinearGradient(
colors: [Colors.teal.shade400, Colors.teal.shade700],
),
onPressed: _simulateWorkflow,
),
const SizedBox(height: 12),
_buildAdvancedButton(
label: 'Generate Multiple Logs',
icon: Icons.bolt,
gradient: LinearGradient(
colors: [Colors.indigo.shade400, Colors.indigo.shade700],
),
onPressed: _generateMultipleLogs,
),
],
),
),
],
),
),
),
),
);
}
Widget _buildSectionCard({
required String title,
required IconData icon,
required Color iconColor,
required Widget child,
}) {
return Card(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, color: iconColor, size: 24),
const SizedBox(width: 12),
Text(
title,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
color: Colors.grey.shade800,
),
),
],
),
const SizedBox(height: 20),
child,
],
),
),
);
}
Widget _buildLogButton({
required String label,
required IconData icon,
required Color color,
required VoidCallback onPressed,
}) {
return ElevatedButton.icon(
onPressed: onPressed,
icon: Icon(icon, size: 22),
label: Text(
label,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: color,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 4,
),
);
}
Widget _buildAdvancedButton({
required String label,
required IconData icon,
required Gradient gradient,
required VoidCallback onPressed,
}) {
return Container(
decoration: BoxDecoration(
gradient: gradient,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onPressed,
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: Colors.white, size: 24),
const SizedBox(width: 12),
Text(
label,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
),
);
}
}