Skip to main content

app_theme_setter 0.0.1 copy "app_theme_setter: ^0.0.1" to clipboard
app_theme_setter: ^0.0.1 copied to clipboard

A powerful, SOLID-compliant dynamic theming package for Flutter. Effortlessly switch themes, customize deep UI elements using extensions, and persist theme selection.

example/lib/main.dart

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

// 1. Implement IThemePersistence (usually with SharedPref or Hive)
class MockThemePersistence implements IThemePersistence {
  String? _savedId;

  @override
  Future<String?> loadThemeId() async {
    // Simulate network or disk delay
    await Future.delayed(const Duration(milliseconds: 500));
    return _savedId;
  }

  @override
  Future<void> saveThemeId(String themeId) async {
    _savedId = themeId;
    debugPrint('Saved theme: $themeId');
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 2. Initialize the controller with available themes and persistence
  final themeController = ThemeController(
    initialTheme: AppLightTheme(),
    persistence: MockThemePersistence(),
    availableThemes: [AppLightTheme(), AppDarkTheme()],
  );

  // 3. Load the saved theme before running the app
  await themeController.init();

  runApp(ThemeExampleApp(controller: themeController));
}

class ThemeExampleApp extends StatelessWidget {
  final ThemeController controller;

  const ThemeExampleApp({super.key, required this.controller});

  @override
  Widget build(BuildContext context) {
    // 4. Wrap the app with ThemeProvider
    return ThemeProvider(
      controller: controller,
      child: Builder(
        builder: (context) {
          // 5. Use ValueListenableBuilder to react to theme changes
          return ValueListenableBuilder<IAppTheme>(
            valueListenable: ThemeProvider.of(context),
            builder: (context, currentTheme, _) {
              return MaterialApp(
                title: 'Dynamic Theme Demo',
                theme: currentTheme.fullThemeData,
                home: const HomeScreen(),
              );
            },
          );
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final themeController = ThemeProvider.of(context);
    final currentTheme = themeController.value;

    // Accessing custom extension data
    final appExtension = Theme.of(context).extension<AppThemeExtension>()!;

    return Scaffold(
      appBar: AppBar(
        title: Text('${currentTheme.name} Demo'),
        actions: [
          IconButton(
            icon: const Icon(Icons.palette),
            onPressed: () => themeController.toggleTheme(),
          ),
        ],
      ),
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [
              appExtension.primaryGradientStart,
              appExtension.primaryGradientEnd,
            ],
          ),
        ),
        child: Padding(
          padding: const EdgeInsets.all(24.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Card(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(
                    appExtension.borderRadius,
                  ),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    children: [
                      Text(
                        'Theme Persistence!',
                        style: Theme.of(context).textTheme.headlineLarge,
                      ),
                      const SizedBox(height: 8),
                      Text(
                        'The choice is saved using MockPersistence.',
                        style: Theme.of(context).textTheme.bodyLarge,
                      ),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 24),
              TextField(
                decoration: appExtension.customFieldDecoration.copyWith(
                  labelText: 'Dynamic Field Decoration',
                  hintText: 'Border and fill change with theme',
                ),
              ),
              const SizedBox(height: 24),
              ElevatedButton(
                onPressed: () {},
                child: const Text('Sample Button'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
150
points
45
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A powerful, SOLID-compliant dynamic theming package for Flutter. Effortlessly switch themes, customize deep UI elements using extensions, and persist theme selection.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on app_theme_setter