flutter_multiple_loaders 1.0.4
flutter_multiple_loaders: ^1.0.4 copied to clipboard
A Flutter package providing a collection of customizable loading animations for your Flutter applications.
import 'dart:math';
import 'package:example/unified_loader_showcase.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
// Enable dark mode toggle
bool _isDarkMode = false;
// Theme mode based on dark mode setting
ThemeMode get themeMode => _isDarkMode ? ThemeMode.dark : ThemeMode.light;
void _toggleDarkMode() {
setState(() {
_isDarkMode = !_isDarkMode;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Multiple Loaders Example',
debugShowCheckedModeBanner: false,
// Light theme
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.light,
),
useMaterial3: true,
),
// Dark theme
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
useMaterial3: true,
),
// Current theme mode
themeMode: themeMode,
// Pass the dark mode toggle function to the main screen
home: MainScreen(
toggleDarkMode: _toggleDarkMode,
isDarkMode: _isDarkMode,
),
);
}
}
class MainScreen extends StatelessWidget {
final Function()? toggleDarkMode;
final bool isDarkMode;
const MainScreen({super.key, this.toggleDarkMode, this.isDarkMode = false});
@override
Widget build(BuildContext context) {
// Get the screen size for responsive layout
final screenSize = MediaQuery.of(context).size;
final bool isSmallScreen = screenSize.width < 600;
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Multiple Loaders'),
elevation: 2,
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 16.0 : screenSize.width * 0.1,
vertical: 24.0,
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Flutter Multiple Loaders',
style: TextStyle(
fontSize: isSmallScreen ? 24 : 32,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
Text(
'A comprehensive collection of customizable loading animations',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isSmallScreen ? 14 : 16,
color: Colors.grey,
),
),
const SizedBox(height: 32),
Wrap(
spacing: 16,
runSpacing: 16,
alignment: WrapAlignment.center,
children: [
_buildNavButton(
context: context,
title: 'All Loaders',
description: 'Explore all loading animations',
destination: const UnifiedLoaderShowcaseFixed(),
color: Colors.deepPurple,
icon: Icons.auto_awesome,
),
],
),
],
),
),
),
),
),
);
}
Widget _buildNavButton({
required BuildContext context,
required String title,
required String description,
required Widget destination,
required Color color,
IconData? icon,
}) {
// Get screen width for responsive sizing
final screenWidth = MediaQuery.of(context).size.width;
final isSmallScreen = screenWidth < 600;
// Calculate responsive width
final buttonWidth =
isSmallScreen
? min(screenWidth * 0.9, 280.0)
: screenWidth < 1200
? 280.0
: 320.0;
// Hero tag for smooth transition
final heroTag = 'hero_${title.toLowerCase().replaceAll(' ', '_')}';
return Hero(
tag: heroTag,
child: Material(
color: Colors.transparent,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0, // No default elevation as we're using custom shadow
),
onPressed:
() => Navigator.of(
context,
).push(MaterialPageRoute(builder: (context) => destination)),
child: Container(
width: buttonWidth,
padding: EdgeInsets.symmetric(
vertical: isSmallScreen ? 16 : 20,
horizontal: isSmallScreen ? 18 : 24,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [color, color.withValues(alpha: 0.7)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: color.withValues(alpha: 0.3),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Row(
children: [
if (icon != null)
Icon(
icon,
color: Colors.white,
size: isSmallScreen ? 28 : 32,
),
SizedBox(width: icon != null ? (isSmallScreen ? 12 : 16) : 0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontSize: isSmallScreen ? 18 : 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 4),
Text(
description,
textAlign: TextAlign.start,
style: TextStyle(
fontSize: isSmallScreen ? 12 : 14,
color: Colors.white.withValues(alpha: 0.8),
),
),
],
),
),
const Icon(Icons.chevron_right, color: Colors.white70),
],
),
),
),
),
);
}
}