Heroine
The queen of hero transitions. Flutter's most addictive interactions.
"this will be such an addictive #FlutterDev interaction!"
Features 🎯
- 🌊 Smooth spring-based hero transitions with customizable bounce and duration
- 🔄 Drag-to-dismiss gestures with velocity-aware animations
- 🎨 Beautiful transition effects with customizable shuttle builders
- 📱 Route-aware transitions that adapt to navigation gestures
- 🎯 Seamless integration with Flutter's navigation system
Try it out
Installation 💻
❗ In order to start using Heroine you must have the Flutter SDK installed on your machine.
Add to your pubspec.yaml
:
dependencies:
heroine: ^latest_version
Or install via flutter pub
:
flutter pub add heroine
Usage 💡
Set up HeroineController for your app
To use heroines in your app, it is important that you register a HeroineController
in your app's navigator.
MaterialApp( // or CupertinoApp, or WidgetsApp
home: MyHomePage(),
navigatorObservers: [HeroineController()],
)
Note: In some nested routing scenarios,
HeroineController
might have to be registered in all of the nested navigators as well.
Basic Hero Transition
Use Heroine
for spring-based hero transitions between routes, just like you would with the Hero
widget:
// In the source route
Heroine(
tag: 'unique-tag',
child: MyWidget(),
)
// In the destination route
Heroine(
tag: 'unique-tag',
child: MyExpandedWidget(),
)
Custom Transition Effects
Choose from predefined shuttle builders or create your own:
Heroine(
tag: 'unique-tag',
flightShuttleBuilder: const FlipShuttleBuilder(
axis: Axis.vertical,
halfFlips: 1,
),
spring: Spring.bouncy, // Customize your springs!
child: MyWidget(),
)
Available shuttle builders:
FadeShuttleBuilder
- Smooth fade transitionFlipShuttleBuilder
- 3D flip animationSingleShuttleBuilder
- Only displays the destination widget – like Flutter's default hero transition
Drag-to-Dismiss
Enable drag-to-dismiss gestures with spring return animations, by wrapping your Heroine
in a DragDismissable
widget:
DragDismissable(
onDismiss: () => Navigator.pop(context),
child: Heroine(
tag: 'unique-tag',
child: MyWidget(),
),
)
Heroine-aware routes
Make your routes respond to Heroine
dismiss gestures:
class MyCustomRoute<T> extends PageRoute<T> with HeroinePageRouteMixin {
// ... your route implementation, see example for more details
}
// React to dismiss gestures in your UI
ReactToHeroineDismiss(
builder: (context, progress, offset, child) {
return Opacity(
opacity: 1 - progress,
child: child,
);
},
child: MyWidget(),
)
This will fade out MyWidget
progressively, as the user dismisses the heroine.
If you look closely at the example GIF, you will see that the details page fades out as the user drags the heroine away.
Spring Configuration 🎯
Heroine uses Springster for spring animations. You can customize the spring behavior:
const mySpring = Spring(
durationSeconds: 0.5, // Settling duration
bounce: 0.2, // Bounce amount (-1 to 1)
);
// Or using damping fraction
const mySpring = Spring.withDamping(
dampingFraction: 0.7,
durationSeconds: 0.5,
);
Advanced Features 🚀
Velocity-Aware Transitions
Provide velocity information for smoother transitions from gestures:
HeroineVelocity(
velocity: dragVelocity,
child: Heroine(
tag: 'unique-tag',
child: MyWidget(),
),
)
Check out the implementation of DragDismissable
, to see how that widget uses HeroineVelocity
to pass the user's drag velocity to the heroine.
Route Transition Duration
You can have Heroine
adjust the timing of its spring to match the duration of the route transition:
Heroine(
tag: 'unique-tag',
adjustToRouteTransitionDuration: true,
child: MyWidget(),
)
For full control however, just pass in a custom Spring
to the Heroine
widget with whatever duration you want.
Best Practices 📝
- Use unique tags for each hero pair
- Keep heroine widget's shapes similar in both routes
- Consider using
adjustToRouteTransitionDuration
for smoother transitions - Test transitions with different spring configurations
- Handle edge cases with custom shuttle builders
Libraries
- heroine
- An evolution on Heroes in Flutter, supporting Spring-based animations as well as cleaner route transitions.