Embed interactive Rive animated icons in Flutter using the rive package with StateMachineController for hover and click state machines.
Open pubspec.yaml and add the rive dependency.
dependencies:
flutter:
sdk: flutter
rive: ^0.13.0Download your icon from Unicorn Icons. Place the .riv file in an assets folder and register it in pubspec.yaml.
flutter:
assets:
- assets/icons/your_icon.rivUse RiveAnimation.asset to load and autoplay the animation. This is the simplest integration — no state machine control required.
import 'package:rive/rive.dart';
class MyIcon extends StatelessWidget {
const MyIcon({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 64,
height: 64,
child: RiveAnimation.asset(
'assets/icons/your_icon.riv',
stateMachines: const ['State Machine 1'],
fit: BoxFit.contain,
),
);
}
}Use StateMachineController to fire the Hover and Click state machine inputs included in every Unicorn Icon. Wrap in a StatefulWidget and use GestureDetector for touch interactions.
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class InteractiveRiveIcon extends StatefulWidget {
const InteractiveRiveIcon({super.key});
@override
State<InteractiveRiveIcon> createState() => _InteractiveRiveIconState();
}
class _InteractiveRiveIconState extends State<InteractiveRiveIcon> {
StateMachineController? _controller;
SMIBool? _hoverInput;
SMITrigger? _clickInput;
void _onRiveInit(Artboard artboard) {
final controller = StateMachineController.fromArtboard(
artboard,
'State Machine 1',
);
if (controller != null) {
artboard.addController(controller);
_controller = controller;
_hoverInput = controller.findInput<bool>('Hover') as SMIBool?;
_clickInput = controller.findInput<bool>('Clicked') as SMITrigger?;
}
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => _hoverInput?.change(true),
onExit: (_) => _hoverInput?.change(false),
child: GestureDetector(
onTap: () => _clickInput?.fire(),
child: SizedBox(
width: 64,
height: 64,
child: RiveAnimation.asset(
'assets/icons/your_icon.riv',
onInit: _onRiveInit,
fit: BoxFit.contain,
),
),
),
);
}
}Use SimpleAnimation or a custom controller to play, pause, or stop the animation from your app's logic.
// Autoplay with loop using SimpleAnimation
RiveAnimation.asset(
'assets/icons/your_icon.riv',
animations: const ['idle'],
fit: BoxFit.contain,
)
// Or trigger a one-shot animation from app state
void triggerSuccess() {
final trigger = _controller?.findInput<bool>('Success') as SMITrigger?;
trigger?.fire();
}Every Unicorn Icon includes state machines named Hover and Clicked on the state machine called State Machine 1. Use controller.findInput<bool> to locate them by name.