Rive animations with State Machine

I want to build a rive animation widget with state machine functionality. Unfortunately the asset can not be loaded from my custom widget, giving me the following error:

Uncaught (in promise) RangeError: Offset is outside the bounds of the DataView

This is my custom widget code:

// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

import 'package:flutter/services.dart'; // Importing Flutter services for asset bundling.
import 'package:rive/rive.dart'; // Importing the Rive package for animations.

// A StatefulWidget for displaying animations with Rive.
class AnimationWidget extends StatefulWidget {
  // Constructor with optional parameters for widget dimensions and animation state.
  const AnimationWidget({
    Key? key,
    this.width,
    this.height,
    this.currentState,
  }) : super(key: key);

  final double? width; // Optional width of the widget.
  final double? height; // Optional height of the widget.
  final String? currentState; // Optional current state of the animation.

  @override
  _AnimationWidgetState createState() => _AnimationWidgetState();
}

// State class for AnimationWidget.
class _AnimationWidgetState extends State<AnimationWidget> {
  Artboard? _riveArtboard; // Private field for Rive artboard.

  @override
  void initState() {
    super.initState();

    // Loading the Rive file from assets.
    rootBundle.load('assets/rive_animations/bat.riv').then(
      (data) async {
        final file = RiveFile.import(data); // Importing the Rive file.

        final artboard = file.mainArtboard; // Getting the main artboard from the file.
        // Creating a state machine controller for the artboard.
        var controller =
            StateMachineController.fromArtboard(artboard, 'State Machine 1');
        if (controller != null) {
          // If the controller is successfully created, add it to the artboard.
          artboard.addController(controller);
        }
        // Update the state to display the artboard.
        setState(() => _riveArtboard = artboard);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    // Building the widget based on the state.
    return SizedBox(
      width: widget.width, // Setting the width.
      height: widget.height, // Setting the height.
      child: _riveArtboard != null
          ? Rive(artboard: _riveArtboard!) // Displaying the Rive artboard if it's not null.
          : Container(), // Showing an empty container if the artboard is null.
    );
  }
}
3
5 replies