Rive Flutter

repository·master·Indexed 23 days ago

https://github.com/rive-app/rive-flutter

A runtime library for integrating and controlling interactive Rive animations and state machines within Flutter applications and games. It provides tools for loading Rive files via FileLoader, selecting artboards and state machines, configuring data bindings, and rendering via RiveWidgetBuilder. The library supports both the Rive and Flutter (Skia/Impeller) renderers and includes utilities for managing native libraries (rive_native) across macOS, Windows, and Linux.

Tokens
4.9K
Snippets
12
Records
30
Agent score
76%

What's inside rive-flutter

  1. Rive platform technology and dependency overview

    master

    Rive integrates its C++ runtime into Flutter using different technologies depending on the target platform. This allows for low-level feature support like advanced text rendering.

    | Platform | Technology | Dependencies                     |
    | -------- | ---------- | -------------------------------- |
    | iOS      | FFI        | statically linked                |
    | Android  | FFI        | `rive_native.so`                   |
    | Windows  | FFI        | `rive_native.dll`                |
    | Mac      | FFI        | statically linked                |
    | Web      | WASM       | `rive_native.js`, `rive_native.wasm` |
  2. Configure Android NDK for Rive

    master

    Rive's runtime uses modern C++ features that require a recent NDK. To ensure compatibility with text features and the Rive runtime on Android, update your android/app/build.gradle file to include a specific ndkVersion. It is recommended to use version 27.2.12479018 or newer.

    android {
      compileSdkVersion 35
      ndkVersion "27.2.12479018"
      ...
    }
  3. Prepare native libraries for testing

    master

    To run flutter test, you must ensure the shared libraries are available. If you haven't run the app on the native platform yet, manually download the prebuilt libraries using the setup script:

    dart run rive_native:setup --verbose --clean --platform <platform>

    Supported --platform values for setup: macos, windows, and linux.

    After the libraries are available, you can run flutter test. You can also optionally build the libraries using the --build flag.

    dart run rive_native:setup --verbose --clean --platform macos
  4. Run the Rive Flutter example using the published package

    master

    To run the example application without building native libraries manually, use the published version of the rive package from Pub. This method avoids potential issues with unpublished versions of rive_native that might be referenced in the GitHub source code.

    Follow these steps:

    1. Unpack the rive package source code.
    2. Navigate to the example directory.
    3. Initialize the Flutter project and fetch dependencies.
    4. Run the application.
    dart pub unpack rive        # Unpack the package source code and example app
    cd rive/example             # Navigate to the example folder
    flutter create .            # Create the platform folders
    flutter pub get             # Fetch dependencies
    flutter run                 # Run the example app
  5. Build `rive_native` from source

    master

    If you prefer to build the native libraries yourself instead of using prebuilt binaries, use the --build flag with the rive_native:setup script.

    Run the following from your project root:

    flutter clean # Important
    flutter pub get
    dart run rive_native:setup --verbose --clean --build --platform <platform>

    Replace <platform> with your target platform (e.g., macos).

    flutter clean # Important
    flutter pub get
    dart run rive_native:setup --verbose --clean --build --platform macos
  6. Run the Rive Flutter example from the GitHub repository

    master

    If you prefer to work directly from the cloned repository, note that you will be required to build the native libraries (rive_native) locally on your machine.

    Follow these steps:

    1. Clone the repository.
    2. Navigate to the example folder.
    3. Fetch dependencies and run the app.
    git clone https://github.com/rive-app/rive-flutter
    cd rive-flutter/example
    flutter pub get
    flutter run
  7. Run the Rive Flutter example app

    master

    To run the example application included in the repository, follow these steps. Note that the example app uses the published version of rive_native from Pub by default.

    dart pub unpack rive        # Unpack the package source code and example app
    cd rive/example             # Navigate to the example folder
    flutter create .            # Create the platform folders
    flutter pub get             # Fetch dependencies
    flutter run                 # Run the example app
  8. Customize the iOS launch screen assets

    master

    To change the image displayed during the app's launch on iOS, you can either replace the image files directly in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode for a more visual approach.

    Using Xcode:

    1. Open your Flutter project's iOS workspace using open ios/Runner.xcworkspace.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch images.
    open ios/Runner.xcworkspace
  9. Use shared textures with RiveWidget

    master

    You can draw a RiveWidget into a shared texture to share the rendered content across different parts of the widget tree (e.g., siblings, separate subtrees, or across routes). This requires using Factory.rive.

    Methods for Shared Textures

    1. Using RivePanel (Implicit): Set useSharedTexture: true. The widget will look up the nearest ancestor RivePanel via an inherited widget.
    2. Using an explicit SharedRenderTexture (Explicit): Provide a sharedTexture instance created via SharedRenderTexture.create. This bypasses the ancestor lookup and allows sharing textures across arbitrary parts of the tree.

    Draw Order

    When using shared textures with Factory.rive, you can use the drawOrder parameter (defaults to 1) to control the stacking order. Higher values draw on top of lower values. Painters sharing a value stack in widget-tree order.

  10. Use RivePanel to improve performance with shared textures

    master

    When using Factory.rive, drawing multiple RiveWidgets to their own individual textures incurs a performance cost and can hit WebGL context limits on the web.

    RivePanel solves this by creating a single shared texture that multiple RiveWidgets can paint to. This can drastically improve performance under certain conditions.

    To enable shared texture behavior:

    1. Wrap your RiveWidgets with a RivePanel.
    2. Set useSharedTexture: true on each RiveWidget.

    Important Considerations:

    • Interleaving: Drawing to a shared surface means you cannot interleave Flutter drawing commands with Rive drawing commands. If you need to interleave content, use Factory.flutter or a separate RivePanel for the interleaved content.
    • Memory: Allocating a larger shared texture has a memory cost. Benchmarking is recommended.
    • Compatibility: This has no effect when using Factory.flutter and will create an unnecessary texture if used there.
    class ExampleRivePanel extends StatelessWidget {
      const ExampleRivePanel({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const RivePanel(
          backgroundColor: Colors.red,
          child: ListViewExample(),
        );
      }
    }
    
    // Inside your widget tree, configure RiveWidget to use the shared texture
    // provided by the parent RivePanel
    RiveWidget(
      controller: state.controller,
      fit: Fit.contain,
      /// Set this to true to draw to the nearest `RivePanel`
      useSharedTexture: true,
    )
  11. Use RiveWidgetBuilder to render Rive files

    master

    RiveWidgetBuilder is a StatefulWidget used to manage the lifecycle of a Rive file, including loading, controller initialization, and data binding. Instead of providing a static widget, you provide a builder function that reacts to the current RiveState.

    Key Parameters

    • fileLoader: A FileLoader used to fetch the Rive file.
    • artboardSelector: Determines which artboard to use (defaults to ArtboardDefault()).
    • stateMachineSelector: Determines which state machine to use (defaults to StateMachineDefault()).
    • dataBind: An optional DataBind instance to bind a view model to the Rive file.
    • builder: A RiveBuilder function that receives the BuildContext and the current RiveState.
    • controller: An optional Controller function to manually create a RiveWidgetController.
    • onLoaded: A callback triggered when the state becomes RiveLoaded.
    • onFailed: A callback triggered when the state becomes RiveFailed.

    Handling RiveState

    The builder function must handle the three possible states of RiveState:

    1. RiveLoading: The file is currently being fetched or initialized.
    2. RiveLoaded: The file is ready. You can access the file, the controller, and the viewModelInstance (if data binding was used).
    3. RiveFailed: An error occurred during loading. You can access the error and stackTrace.