Search code examples
flutterflutter-dependenciesflutter-animation

Flutter Rive animate after tap


I'm new using Rive and I want to use it in a proyect but I don't know very well how to animate it after tap, I'm using https://editor.rive.app/preview/2063-4080-flutter-puzzle-hack-project/381484?mode=animate&artboard=birb&animation=birb

I tried with this code but Throw me an error "Expected a value of type 'SMITrigger', but got one of type 'SMIBool'

I tried the bird look up after tap

    class GlassCard extends StatefulWidget {
  const GlassCard({super.key});

  @override
  State<GlassCard> createState() => _GlassCardState();
}

class _GlassCardState extends State<GlassCard> {
  String animation = 'idle';
  //animation
  Artboard? _birdArtboard;
  SMITrigger? trigger;
  StateMachineController? stateMachineController;

  @override
  void initState() {
    super.initState();
    rootBundle.load('assets/bird.riv').then(
      (data) {
        final file = RiveFile.import(data);
        final artboard = file.mainArtboard;
        stateMachineController =
            StateMachineController.fromArtboard(artboard, "birb");
        if (stateMachineController != null) {
          artboard.addController(stateMachineController!);
          trigger = stateMachineController!.findSMI('look up');

          for (var e in stateMachineController!.inputs) {
            debugPrint(e.runtimeType.toString());
            debugPrint("name ${e.name} End");
          }
          trigger = stateMachineController!.inputs.first as SMITrigger;
        }

        setState(() => _birdArtboard = artboard);
      },
    );
  }

  void lookup() {
    trigger?.fire();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        height: 400,
        width: 400,
        child: _birdArtboard == null
            ? const SizedBox()
            : Center(
                child: GestureDetector(
                  onTap: () {
                    lookup();
                  },
                  child: Rive(artboard: _birdArtboard!),
                ),
              ),
      ),
    );
  }
}

Thank you


Solution

  • This error occurs because of the following line in your code : -

    trigger = stateMachineController!.inputs.first as SMITrigger;
    

    The reason for it is that type casting is invalid.

    You don't need that line to run and interact with the rive inputs. To interact with the inputs, you just have to use proper data type for the variables. I have added a small example with a single tap the bird looks up and on double tap, it enables and disables the dancing of the bird.

    Complete Code : -

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:rive/rive.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'List',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          debugShowCheckedModeBanner: false,
          home: const GlassCard(),
        );
      }
    }
    
    class GlassCard extends StatefulWidget {
      const GlassCard({super.key});
    
      @override
      State<GlassCard> createState() => _GlassCardState();
    }
    
    class _GlassCardState extends State<GlassCard> {
      String animation = 'idle';
    
      Artboard? _birdArtboard;
      SMITrigger? trigger;
      SMIBool? dance;
    
      StateMachineController? stateMachineController;
    
      @override
      void initState() {
        super.initState();
        rootBundle.load('assets/bird.riv').then(
          (data) {
            final file = RiveFile.import(data);
            final artboard = file.mainArtboard;
            stateMachineController =
                StateMachineController.fromArtboard(artboard, "birb");
            if (stateMachineController != null) {
              artboard.addController(stateMachineController!);
    
              trigger = stateMachineController!.findSMI('look up');
    
              dance = stateMachineController!.findSMI('dance');
            }
    
            setState(() => _birdArtboard = artboard);
          },
        );
      }
    
      void lookup() {
        trigger?.fire();
      }
    
      void danceBird() {
        dance?.change(!dance!.value);
      }
    
      @override
    
          Widget build(BuildContext context) {
            return Center(
              child: SizedBox(
                height: 400,
                width: 400,
                child: _birdArtboard == null
                    ? const SizedBox()
                    : Center(
                        child: GestureDetector(
                          onTap: () {
                            lookup();
                          },
                          onDoubleTap: () {
                            danceBird();
                          },
                          child: Rive(artboard: _birdArtboard!),
                        ),
                      ),
              ),
            );
          }
        }
    

    Output : -