rodrigobastosv / loading_overlay

MIT License
114 stars 29 forks source link

Theming GlobalLoaderOverlay #74

Closed xErik closed 1 day ago

xErik commented 4 days ago

Is it possible to make GlobalLoaderOverlay respect the current Theme?

I tried to use a Scaffold wrapped in a Theme that pulls its ThemeData from a global ThemeService.

However, the dark / light themes did not get applied.

rodrigobastosv commented 3 days ago

Hey @xErik , thanks for using this package. GlobalLoaderOverlay shouldn't interfere at all with Theme or ThemeData. GlobalLoaderOverlay just wraps the MaterialApp without affecting it.

xErik commented 2 days ago

Sorry, I have expressed myself to vaguely.

Setting an app to dark mode, I would expect GlobalLoaderOverlay to show in dark mode too.

Wrapping the overlay in a Theme does the trick though, as demonstrated below. I wonder if there is an easier way using two theme mode switches?

This app allows to switch between dark and light theme mode for the overlay:

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

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool isDark = true;

  @override
  Widget build(BuildContext context) {
    return GlobalLoaderOverlay(
      useDefaultLoading: false,

      // NOT WORKING:
      // overlayWidgetBuilder: (_) => _getContentOverlay(),

      // IS WORKING:
      overlayWidgetBuilder: (_) => Theme(
          data: isDark
              ? ThemeData.dark(useMaterial3: true)
              : ThemeData.light(useMaterial3: true),
          child: _getContentOverlay()),

      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        themeMode: isDark ? ThemeMode.dark : ThemeMode.light,
        theme: ThemeData.light(useMaterial3: true),
        darkTheme: ThemeData.dark(useMaterial3: true),
        home: Scaffold(
          body: _getContentScreen(),
        ),
      ),
    );
  }

  Widget _getContentOverlay() {
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ElevatedButton(
              onPressed: () => setState(() => isDark = !isDark),
              child: const Text('Toggle theme mode')),
          ElevatedButton(
              onPressed: () => context.loaderOverlay.hide(),
              child: const Text('Hide Overlay')),
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                children: [
                  Text('Loading',
                      style: Theme.of(context).textTheme.headlineLarge),
                  const Text('6 %'),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget _getContentScreen() {
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ElevatedButton(
              onPressed: () => setState(() => isDark = !isDark),
              child: const Text('Toggle theme mode')),
          ElevatedButton(
              onPressed: () => context.loaderOverlay.show(),
              child: const Text('Show Overlay')),
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                children: [
                  Text('Loading',
                      style: Theme.of(context).textTheme.headlineLarge),
                  const Text('6 %'),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}
rodrigobastosv commented 1 day ago

Thanks for the added context @xErik . I don't plan to bloat the API of the package adding this. Right now it's possible to switch this so i think it's better to not bring this responsibility to inside the package.