Files
Edouard Marquez e3bc40fdf3 chore: Migration to Dart 3.8 (#6668)
* Migration to Dart 3.8

* New GA

* Fix dartdoc
2025-06-23 18:14:17 +02:00

93 lines
2.6 KiB
Dart

import 'package:flutter/material.dart';
/// A custom [Hero] widget that allows to listen to the end of the animation.
/// This code is mainly a copy/paste from the Flutter widget, but some methods
/// are private.
///
/// The goal here, is to be notified when the animation is finished and
/// thus trigger an autofocus event at the perfect timing.
class SmoothHero extends StatelessWidget {
const SmoothHero({
required this.tag,
required this.enabled,
required this.child,
this.onAnimationEnded,
super.key,
}) : assert(!enabled || tag != null);
final Object? tag;
final bool enabled;
final Widget child;
final Function(HeroFlightDirection direction)? onAnimationEnded;
@override
Widget build(BuildContext context) {
return HeroMode(
enabled: enabled,
child: Hero(
tag: tag ?? '',
flightShuttleBuilder: onAnimationEnded == null
? null
: _flightShuttleBuilder,
child: child,
),
);
}
Widget _flightShuttleBuilder(
BuildContext flightContext,
Animation<double> animation,
HeroFlightDirection flightDirection,
BuildContext fromHeroContext,
BuildContext toHeroContext,
) {
animation.addStatusListener((AnimationStatus status) {
_onAnimationStatusChanged(status, flightDirection);
});
/// Code from [heroes.dart]
final Hero toHero = toHeroContext.widget as Hero;
final MediaQueryData? toMediaQueryData = MediaQuery.maybeOf(toHeroContext);
final MediaQueryData? fromMediaQueryData = MediaQuery.maybeOf(
fromHeroContext,
);
if (toMediaQueryData == null || fromMediaQueryData == null) {
return toHero.child;
}
final EdgeInsets fromHeroPadding = fromMediaQueryData.padding;
final EdgeInsets toHeroPadding = toMediaQueryData.padding;
return AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: toMediaQueryData.copyWith(
padding: (flightDirection == HeroFlightDirection.push)
? EdgeInsetsTween(
begin: fromHeroPadding,
end: toHeroPadding,
).evaluate(animation)
: EdgeInsetsTween(
begin: toHeroPadding,
end: fromHeroPadding,
).evaluate(animation),
),
child: toHero.child,
);
},
);
}
void _onAnimationStatusChanged(
AnimationStatus status,
HeroFlightDirection direction,
) {
if (status == AnimationStatus.completed) {
onAnimationEnded?.call(direction);
}
}
}