flutter_progress_loading 0.0.9
flutter_progress_loading: ^0.0.9 copied to clipboard
A lightweight and efficient loading and toast widget for Flutter, requiring no BuildContext. Supports Android, iOS, Web, Windows, macOS, and Linux for a seamless user experience.
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_progress_loading/flutter_progress_loading.dart';
import './custom_animation.dart';
import './test.dart';
void main() {
runApp(const MyApp());
configLoading();
}
void configLoading() {
ProgressLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = ProgressLoadingIndicatorType.fadingCircle
..loadingStyle = ProgressLoadingStyle.dark
..indicatorSize = 45.0
..radius = 10.0
..progressColor = Colors.yellow
..backgroundColor = Colors.green
..indicatorColor = Colors.yellow
..textColor = Colors.yellow
..maskColor = Colors.blue.withAlpha((0.5 * 255).toInt())
..userInteractions = true
..dismissOnTap = false
..customAnimation = CustomAnimation();
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ProgressLoading Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.indigo,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.indigo,
brightness: Brightness.light,
),
cardTheme: const CardThemeData(
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))),
),
),
home: const MyHomePage(title: 'ProgressLoading'),
builder: ProgressLoading.init(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, this.title});
final String? title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Timer? _timer;
late double _progress;
late ProgressLoadingStyle _style;
late ProgressLoadingMaskType _maskType;
late ProgressLoadingToastPosition _toastPosition;
late ProgressLoadingAnimationStyle _animationStyle;
late ProgressLoadingIndicatorType _indicatorType;
@override
void initState() {
super.initState();
_style = ProgressLoading.instance.loadingStyle;
_maskType = ProgressLoading.instance.maskType;
_toastPosition = ProgressLoading.instance.toastPosition;
_animationStyle = ProgressLoading.instance.animationStyle;
_indicatorType = ProgressLoading.instance.indicatorType;
ProgressLoading.addStatusCallback((status) {
debugPrint('ProgressLoading Status $status');
if (status == ProgressLoadingStatus.dismiss) {
_timer?.cancel();
}
});
ProgressLoading.showSuccess('Ready to load!');
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
body: CustomScrollView(
slivers: [
_buildAppBar(),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildActionGrid(),
const SizedBox(height: 24),
_buildSectionHeader('Configuration', Icons.settings_suggest),
const SizedBox(height: 12),
_buildSectionCard(
title: 'Loading Style',
icon: Icons.palette_outlined,
child: CupertinoSegmentedControl<ProgressLoadingStyle>(
selectedColor: Theme.of(context).primaryColor,
groupValue: _style,
children: const {
ProgressLoadingStyle.dark: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Dark'),
),
ProgressLoadingStyle.light: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Light'),
),
ProgressLoadingStyle.custom: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Custom'),
),
},
onValueChanged: (value) {
setState(() => _style = value);
ProgressLoading.instance.loadingStyle = value;
},
),
),
_buildSectionCard(
title: 'Mask Type',
icon: Icons.layers_outlined,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CupertinoSegmentedControl<ProgressLoadingMaskType>(
selectedColor: Theme.of(context).primaryColor,
groupValue: _maskType,
children: const {
ProgressLoadingMaskType.none: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('None'),
),
ProgressLoadingMaskType.clear: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Clear'),
),
ProgressLoadingMaskType.black: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Black'),
),
ProgressLoadingMaskType.custom: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Custom'),
),
},
onValueChanged: (value) {
setState(() => _maskType = value);
ProgressLoading.instance.maskType = value;
},
),
),
),
_buildSectionCard(
title: 'Toast Position',
icon: Icons.align_vertical_bottom_outlined,
child: CupertinoSegmentedControl<ProgressLoadingToastPosition>(
selectedColor: Theme.of(context).primaryColor,
groupValue: _toastPosition,
children: const {
ProgressLoadingToastPosition.top: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Top'),
),
ProgressLoadingToastPosition.center: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Center'),
),
ProgressLoadingToastPosition.bottom: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Bottom'),
),
},
onValueChanged: (value) {
setState(() => _toastPosition = value);
ProgressLoading.instance.toastPosition = value;
},
),
),
_buildSectionCard(
title: 'Animation Style',
icon: Icons.animation_outlined,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CupertinoSegmentedControl<ProgressLoadingAnimationStyle>(
selectedColor: Theme.of(context).primaryColor,
groupValue: _animationStyle,
children: const {
ProgressLoadingAnimationStyle.opacity: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Opacity'),
),
ProgressLoadingAnimationStyle.offset: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Offset'),
),
ProgressLoadingAnimationStyle.scale: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Scale'),
),
ProgressLoadingAnimationStyle.custom: Padding(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Text('Custom'),
),
},
onValueChanged: (value) {
setState(() => _animationStyle = value);
ProgressLoading.instance.animationStyle = value;
},
),
),
),
_buildSectionCard(
title: 'Indicator Type',
icon: Icons.hourglass_empty_outlined,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CupertinoSegmentedControl<ProgressLoadingIndicatorType>(
selectedColor: Theme.of(context).primaryColor,
groupValue: _indicatorType,
children: const {
ProgressLoadingIndicatorType.fadingCircle: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Fading'),
),
ProgressLoadingIndicatorType.circle: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Circle'),
),
ProgressLoadingIndicatorType.wave: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Wave'),
),
ProgressLoadingIndicatorType.ring: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Ring'),
),
ProgressLoadingIndicatorType.pulse: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Pulse'),
),
ProgressLoadingIndicatorType.cubeGrid: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Cube'),
),
ProgressLoadingIndicatorType.threeBounce: Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text('Bounce'),
),
},
onValueChanged: (value) {
setState(() => _indicatorType = value);
ProgressLoading.instance.indicatorType = value;
},
),
),
),
const SizedBox(height: 50),
],
),
),
),
],
),
);
}
Widget _buildAppBar() {
return SliverAppBar(
expandedHeight: 180.0,
floating: false,
pinned: true,
backgroundColor: Colors.indigo,
flexibleSpace: FlexibleSpaceBar(
title: Text(widget.title ?? '',
style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white)),
background: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.indigo, Colors.deepPurple],
),
),
child: Center(
child: Icon(Icons.rocket_launch,
size: 80,
color: Colors.white.withAlpha((0.2 * 255).toInt())),
),
),
),
actions: [
IconButton(
icon: const Icon(Icons.bug_report_outlined, color: Colors.white),
onPressed: () {
_timer?.cancel();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const TestPage()),
);
},
),
],
);
}
Widget _buildActionGrid() {
return Column(
children: [
Row(
children: [
Expanded(child: _buildActionButton('Show Loading', Icons.play_arrow, Colors.indigo, () async {
_timer?.cancel();
await ProgressLoading.show(status: 'Processing...', maskType: _maskType);
})),
const SizedBox(width: 12),
Expanded(child: _buildActionButton('Dismiss All', Icons.close, Colors.redAccent, () async {
_timer?.cancel();
await ProgressLoading.dismiss();
})),
],
),
const SizedBox(height: 12),
Row(
children: [
Expanded(child: _buildActionButton('Success', Icons.check_circle_outline, Colors.green, () async {
_timer?.cancel();
await ProgressLoading.showSuccess('Operation Successful!');
})),
const SizedBox(width: 12),
Expanded(child: _buildActionButton('Error', Icons.error_outline, Colors.orange, () {
_timer?.cancel();
ProgressLoading.showError('Something went wrong!');
})),
],
),
const SizedBox(height: 12),
_buildActionButton('Run Progress', Icons.trending_up, Colors.blue, () {
_progress = 0;
_timer?.cancel();
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
ProgressLoading.showProgress(_progress, status: '${(_progress * 100).toStringAsFixed(0)}%');
_progress += 0.03;
if (_progress >= 1) {
_timer?.cancel();
ProgressLoading.showSuccess('Download finished!');
}
});
}, isFullWidth: true),
],
);
}
Widget _buildActionButton(String label, IconData icon, Color color, VoidCallback onPressed, {bool isFullWidth = false}) {
return ElevatedButton.icon(
onPressed: onPressed,
icon: Icon(icon, size: 20, color: Colors.white),
label: Text(label, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
style: ElevatedButton.styleFrom(
backgroundColor: color,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
elevation: 1,
),
);
}
Widget _buildSectionHeader(String title, IconData icon) {
return Row(
children: [
Icon(icon, size: 20, color: Colors.indigo),
const SizedBox(width: 8),
Text(title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.indigo)),
],
);
}
Widget _buildSectionCard({required String title, required IconData icon, required Widget child}) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, size: 18, color: Colors.grey[600]),
const SizedBox(width: 8),
Text(title, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.grey[700])),
],
),
const SizedBox(height: 12),
SizedBox(width: double.infinity, child: Center(child: child)),
],
),
),
);
}
}