flutter_progress_loading 0.0.9 copy "flutter_progress_loading: ^0.0.9" to clipboard
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.

example/lib/main.dart

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)),
          ],
        ),
      ),
    );
  }
}
5
likes
160
points
25
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

back_button_interceptor, flutter, flutter_spinkit

More

Packages that depend on flutter_progress_loading