company_branded_loader 0.0.2 copy "company_branded_loader: ^0.0.2" to clipboard
company_branded_loader: ^0.0.2 copied to clipboard

A customizable Flutter branded loader overlay with animated company text, canvas effects, blur, and dynamic API status support.

example/lib/main.dart

import 'package:company_branded_loader/company_branded_loader.dart';
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF00A6C7),
          brightness: Brightness.light,
        ),
        scaffoldBackgroundColor: const Color(0xFFF4F8FC),
        appBarTheme: const AppBarTheme(centerTitle: true),
        useMaterial3: true,
      ),
      home: const ExampleHomeScreen(),
    );
  }
}

enum LoaderDemoMode { basic, dynamic, custom }

class ExampleHomeScreen extends StatefulWidget {
  const ExampleHomeScreen({super.key});

  @override
  State<ExampleHomeScreen> createState() => _ExampleHomeScreenState();
}

class _ExampleHomeScreenState extends State<ExampleHomeScreen> {
  bool isLoading = false;
  String? statusText;
  LoaderDemoMode mode = LoaderDemoMode.dynamic;

  Future<void> simulateApiCall() async {
    final useStatusFlow = mode != LoaderDemoMode.basic;

    setState(() {
      isLoading = true;
      statusText = useStatusFlow ? 'Fetching data' : null;
    });

    await Future<void>.delayed(const Duration(seconds: 1));
    if (!mounted) {
      return;
    }

    if (useStatusFlow) {
      setState(() {
        statusText = 'Processing request';
      });
    }

    await Future<void>.delayed(const Duration(seconds: 1));
    if (!mounted) {
      return;
    }

    if (useStatusFlow) {
      setState(() {
        statusText = 'Finalizing';
      });
    }

    await Future<void>.delayed(const Duration(seconds: 1));
    if (!mounted) {
      return;
    }

    setState(() {
      isLoading = false;
      statusText = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;
    final accentColor = switch (mode) {
      LoaderDemoMode.basic => const Color(0xFF00E5FF),
      LoaderDemoMode.dynamic => const Color(0xFF36CFFF),
      LoaderDemoMode.custom => const Color(0xFFFF7A59),
    };

    return CompanyBrandedLoaderOverlay(
      isLoading: isLoading,
      companyName: 'CoreDron',
      dynamicStatusText: statusText,
      accentColor: accentColor,
      customAnimation: mode == LoaderDemoMode.custom
          ? _ExampleCustomAnimation(accentColor: accentColor)
          : null,
      child: Scaffold(
        appBar: AppBar(title: const Text('Branded Loader Example')),
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  padding: const EdgeInsets.all(20),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(28),
                    gradient: LinearGradient(
                      begin: Alignment.topLeft,
                      end: Alignment.bottomRight,
                      colors: [
                        colorScheme.primary.withValues(alpha: 0.12),
                        colorScheme.secondary.withValues(alpha: 0.08),
                      ],
                    ),
                    border: Border.all(
                      color: Colors.white.withValues(alpha: 0.7),
                    ),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Premium Loader Modes',
                        style: Theme.of(context)
                            .textTheme
                            .headlineSmall
                            ?.copyWith(fontWeight: FontWeight.w700),
                      ),
                      const SizedBox(height: 8),
                      Text(
                        'Switch between a simple brand overlay, dynamic API statuses, and a custom animation slot.',
                        style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                              color: const Color(0xFF4B5563),
                            ),
                      ),
                      const SizedBox(height: 18),
                      Wrap(
                        spacing: 10,
                        runSpacing: 10,
                        children: [
                          _ModeChip(
                            label: 'Basic',
                            selected: mode == LoaderDemoMode.basic,
                            onTap: () => setState(() {
                              mode = LoaderDemoMode.basic;
                            }),
                          ),
                          _ModeChip(
                            label: 'Dynamic Status',
                            selected: mode == LoaderDemoMode.dynamic,
                            onTap: () => setState(() {
                              mode = LoaderDemoMode.dynamic;
                            }),
                          ),
                          _ModeChip(
                            label: 'Custom Animation',
                            selected: mode == LoaderDemoMode.custom,
                            onTap: () => setState(() {
                              mode = LoaderDemoMode.custom;
                            }),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 20),
                Expanded(
                  child: Container(
                    width: double.infinity,
                    padding: const EdgeInsets.all(24),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(30),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withValues(alpha: 0.06),
                          blurRadius: 28,
                          offset: const Offset(0, 16),
                        ),
                      ],
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Current Configuration',
                          style: Theme.of(context)
                              .textTheme
                              .titleLarge
                              ?.copyWith(fontWeight: FontWeight.w700),
                        ),
                        const SizedBox(height: 14),
                        Text(
                          switch (mode) {
                            LoaderDemoMode.basic =>
                              'Shows the premium default loader with the built-in orbit animation.',
                            LoaderDemoMode.dynamic =>
                              'Adds staged API messages: Fetching data, Processing request, then Finalizing.',
                            LoaderDemoMode.custom =>
                              'Replaces the canvas loader with a custom animation widget while keeping the same overlay shell.',
                          },
                          style:
                              Theme.of(context).textTheme.bodyLarge?.copyWith(
                                    color: const Color(0xFF4B5563),
                                    height: 1.45,
                                  ),
                        ),
                        const Spacer(),
                        SizedBox(
                          width: double.infinity,
                          child: FilledButton(
                            onPressed: simulateApiCall,
                            style: FilledButton.styleFrom(
                              backgroundColor: accentColor,
                              foregroundColor: const Color(0xFF04131A),
                              padding: const EdgeInsets.symmetric(vertical: 18),
                              textStyle: const TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.w700,
                              ),
                            ),
                            child: const Text('Start API Call'),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _ModeChip extends StatelessWidget {
  const _ModeChip({
    required this.label,
    required this.selected,
    required this.onTap,
  });

  final String label;
  final bool selected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(999),
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 220),
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        decoration: BoxDecoration(
          color: selected
              ? const Color(0xFF071A22)
              : const Color(0xFFFFFFFF).withValues(alpha: 0.72),
          borderRadius: BorderRadius.circular(999),
          border: Border.all(
            color: selected
                ? Colors.white.withValues(alpha: 0.14)
                : const Color(0xFFD7E4F2),
          ),
        ),
        child: Text(
          label,
          style: TextStyle(
            color: selected ? Colors.white : const Color(0xFF24323D),
            fontWeight: FontWeight.w600,
          ),
        ),
      ),
    );
  }
}

class _ExampleCustomAnimation extends StatefulWidget {
  const _ExampleCustomAnimation({required this.accentColor});

  final Color accentColor;

  @override
  State<_ExampleCustomAnimation> createState() =>
      _ExampleCustomAnimationState();
}

class _ExampleCustomAnimationState extends State<_ExampleCustomAnimation>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1400),
    )..repeat(reverse: true);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox.square(
      dimension: 96,
      child: AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          final t = Curves.easeInOut.transform(_controller.value);
          return Transform.scale(
            scale: 0.92 + (0.1 * t),
            child: DecoratedBox(
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                gradient: RadialGradient(
                  colors: [
                    widget.accentColor.withValues(alpha: 0.9),
                    widget.accentColor.withValues(alpha: 0.14),
                  ],
                ),
                boxShadow: [
                  BoxShadow(
                    color: widget.accentColor.withValues(alpha: 0.35),
                    blurRadius: 24,
                    spreadRadius: 3,
                  ),
                ],
              ),
              child: Center(
                child: Icon(
                  Icons.auto_awesome_rounded,
                  size: 40,
                  color: Colors.white.withValues(alpha: 0.96),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
0
likes
160
points
28
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A customizable Flutter branded loader overlay with animated company text, canvas effects, blur, and dynamic API status support.

Repository (GitHub)
View/report issues

Topics

#loader #overlay #animation #ui

License

MIT (license)

Dependencies

flutter

More

Packages that depend on company_branded_loader