changeTheme method

void changeTheme(
  1. BuildContext context, {
  2. required ThemeData theme,
  3. required GlobalKey<State<StatefulWidget>> key,
  4. Offset? offset,
  5. VoidCallback? onAnimationFinish,
})

Triggers the theme change animation.

context is required to access the devicePixelRatio. theme is the new theme to switch to. key is the GlobalKey of the widget from which the shockwave animation will originate (e.g. the button tapped). offset is an optional offset from the center of the widget identified by key. onAnimationFinish is an optional callback called when the transition is fully complete.

Implementation

void changeTheme(
  BuildContext context, {
  required ThemeData theme,
  required GlobalKey key,
  Offset? offset,
  VoidCallback? onAnimationFinish,
}) async {
  if (_isAnimating) return;
  final devicePixelRatio = View.of(context).devicePixelRatio;

  // 1. Capture the current (old) theme screenshot BEFORE updating the theme.
  // This prevents race conditions where an interim rebuild (during await)
  // would show the new theme before we are ready to animate.
  final image = await _makeScreenshot(devicePixelRatio);

  // 2. Now update the state atomically
  _isAnimating = true;
  oldTheme = _theme;
  _theme = theme;
  switcherOffset = _getSwitcherCoordinates(key, offset);

  // 3. Manage resources
  oldThemeImage?.dispose();
  oldThemeImage = image;

  // 4. Trigger the update
  notifyListeners();
}