animated_theme_switcher

repository·master·Indexed 43 days ago

https://github.com/kherel/animated_theme_switcher

A Flutter library for creating smooth, animated transitions between different ThemeData configurations. It provides the ThemeProvider for theme management, ThemeSwitchingArea to define animation boundaries, and ThemeSwitcher to trigger transitions. Supports custom animation shapes via ThemeSwitcherClipper, including a circular transition with ThemeSwitcherCircleClipper. Requires the CanvasKit rendering engine for web support.

Tokens
2.6K
Snippets
14
Records
15
Agent score
54%

What's inside animated_theme_switcher

  1. Important usage notes for web and persistence

    master

    Web Support

    To use this library on the web, you must use the CanvasKit rendering engine.

    Theme Persistence

    This package does not automatically persist the selected theme to local storage. To save the user's theme preference, you must implement your own logic (e.g., using the shared_preferences package).

  2. Configure ThemeProvider for MaterialApp

    master

    To enable theme switching across your entire application, wrap your MaterialApp with the ThemeProvider widget. You must provide an initTheme (the initial ThemeData) and a builder that returns the MaterialApp using the provided myTheme.

    ThemeProvider(
        initTheme: initTheme,
        builder: (context, myTheme) {
          return MaterialApp(
            title: 'Flutter Demo',
            theme: myTheme,
            home: MyHomePage(),
          );
        }),
  3. Use ThemeSwitchingArea to define animation boundaries

    master

    Wrap the specific screen or area where you want the theme switching animation to occur with the ThemeSwitchingArea widget. This defines the scope of the transition.

    ThemeSwitchingArea(
      child: Builder(builder: (context) {
        return ...;
      }),
    );
  4. Use ThemeSwitcher convenience constructors

    master

    The library provides two alternative constructors that simplify access to the switcher and the current theme via their builders:

    1. ThemeSwitcher.switcher(): Provides the switcher instance directly in the builder.
    2. ThemeSwitcher.withTheme(): Provides both the switcher instance and the current theme in the builder.
    // Using ThemeSwitcher.switcher()
    ThemeSwitcher.switcher(
      builder: (context, switcher) {
        ...
        onTap: () => switcher.changeTheme(
          theme: newTheme,
        );
        ...
      },
    );
    
    // Using ThemeSwitcher.withTheme()
    ThemeSwitcher.withTheme(
      builder: (context, switcher, theme) {
        ...
        onTap: () => switcher.changeTheme(
          theme: theme.brightness == Brightness.light
              ? darkTheme
              : lightTheme,
        );
        ...
      },
    );
  5. Switch themes using ThemeSwitcher

    master

    To trigger a theme change, wrap your switcher UI (like a button) with a ThemeSwitcher builder. You can access the theme switching logic via ThemeSwitcher.of(context).changeTheme().

    changeTheme accepts:

    • theme: The new ThemeData to apply.
    • isReversed: A boolean to reverse the animation direction (defaults to false).
    ThemeData newTheme = ThemeData(
      primaryColor: Colors.amber
    );
    ...
    ThemeSwitcher(
      builder: (context) {
        ...
        onTap: () => ThemeSwitcher.of(context).changeTheme(
          theme: newTheme,
          isReversed: false // default: false 
        );
        ...
      },
    );
  6. Use ThemeSwitchingArea to define the scope of theme transitions

    master

    The ThemeSwitchingArea widget is used to wrap the part of your widget tree where you want the animated theme transition to occur. It acts as the boundary for the animation, ensuring that the transition between the old theme and the new theme is visually contained within this area.

    When a theme change is triggered, ThemeSwitchingArea manages a Stack containing the current theme's content and a clipped layer representing the new theme (or a snapshot of the old one), using a ClipPath to create the animation effect.

    ThemeSwitchingArea(
      child: YourAppContentWidget(),
    )
  7. Access ThemeSwitcherState via ThemeSwitcher.of()

    master

    To trigger a theme change from a widget located deep in the widget tree, use ThemeSwitcher.of(context). This method retrieves the ThemeSwitcherState from the nearest ThemeSwitcher ancestor.

    Note: This requires the widget to be a descendant of a ThemeSwitcher widget.

    void _onPressed(BuildContext context) {
      final switcher = ThemeSwitcher.of(context);
      switcher.changeTheme(theme: ThemeData.light());
    }
  8. Use the ThemeSwitcher widget to trigger theme transitions

    master

    The ThemeSwitcher widget is the primary entry point for implementing animated theme changes. It provides a context in which you can trigger a transition between themes using a specified clipper (which defines the shape of the animation).

    There are three ways to instantiate ThemeSwitcher:

    1. Standard Constructor: Requires a builder function that receives only BuildContext.
    2. ThemeSwitcher.switcher factory: A convenience constructor that automatically provides the ThemeSwitcherState to your builder via ThemeSwitcher.of(context).
    3. ThemeSwitcher.withTheme factory: A convenience constructor that provides both the ThemeSwitcherState and the current ThemeData to your builder.

    To trigger the animation, call changeTheme on the ThemeSwitcherState instance.

    // Using the .switcher factory for easy access to the state
    ThemeSwitcher.switcher(
      clipper: const ThemeSwitcherCircleClipper(),
      builder: (context, switcher) {
        return IconButton(
          icon: Icon(Icons.brightness_6),
          onPressed: () {
            // Trigger the animated transition
            switcher.changeTheme(theme: ThemeData.dark());
          },
        );
      },
    );
  9. Access the current theme using ThemeModel.of()

    master

    To trigger theme changes or access the current ThemeData from anywhere within the ThemeProvider widget tree, use ThemeModel.of(context). This returns the ThemeModel instance associated with the provider.

    This method allows you to access the current theme, check if an animation isAnimating, and call changeTheme to perform a transition.

    final model = ThemeModel.of(context);
    final currentTheme = model.theme;