Skip to main content
DEPRECATION NOTICE: This entire page documents the legacy Events system. For new projects: Use Data Binding instead. For existing projects: Plan to migrate from Events to Data Binding as soon as possible. This content is provided for legacy support only.
With Rive events, you have the ability to subscribe to meaningful signals that get reported from animations, state machines, and Rive listeners, all created at design time from the Rive editor. These signals can be subscribed to at runtime and have a specific name, type, and various custom metadata that may accompany the event to help inform the context surrounding its meaning. For more on the Events feature in general, check out the Events page in the editor section of the docs. The Event system has also been expanded to support Audio Events to trigger audio to play in the editor and at runtime. For example, in a Rive graphic simulating a loader, there may be an event named LoadComplete fired when transitioning from a complete timeline animation state to an idle state. You can subscribe to Rive events with a callback that the runtime may invoke, and from there, your callback can handle extra functionality at just the right moment when the event fired. Other practical use cases for events:
  • Coordinating audio playback at specific moments in an animation, see Audio Events
  • Opening a URL when specific interactions have occurred
  • Adding haptic feedback on meaningful touch interactions
  • Implementing functionality on Buttons and other UI elements
  • Send semantic information
  • Communicate any information your runtime needs at the right moment

Subscribing to Events

When you subscribe to Rive events at runtime, you subscribe to all Rive events that may be emitted from a state machine, and you can parse through each event by name or type to execute conditional logic. Let’s use a 5-star rater Rive example to set any text supplied with events and open a URL if one is given.

Adding an Event Listener

Use the addEventListener and removeEventListener on RiveAnimationView to subscribe/unsubscribe aRiveFileController.RiveEventListener. This listener receives either an OpenURLRiveEvent or GeneralRiveEvent of type RiveEvent.
/// Access the RiveAnimationView
private val yourRiveAnimationView: RiveAnimationView by lazy(LazyThreadSafetyMode.NONE) {
    findViewById(R.id.your_animation_view)
}

...

/// Create a RiveEventListener
val eventListener = object : RiveFileController.RiveEventListener {
    override fun notifyEvent(event: RiveEvent) {
        when (event) {
            is OpenURLRiveEvent -> {
                Log.i("RiveEvent", "Open URL Rive event: ${event.url}")
            }
            is GeneralRiveEvent -> {
                Log.i("RiveEvent", "General Rive event")
            }
        }
        Log.i("RiveEvent", "name: ${event.name}")
        Log.i("RiveEvent", "type: ${event.type}")
        Log.i("RiveEvent", "properties: ${event.properties}")
        // `data` contains all information in the event
        Log.i("RiveEvent", "data: ${event.data}");
    }
}

/// Attach the listener
yourRiveAnimationView.addEventListener(eventListener);

...

/// Remove when no longer needed
override fun onDestroy() {
    yourRiveAnimationView.removeEventListener(eventListener);
    super.onDestroy()
}
The Rive Android Runtime is executed on a separate thread. Any UI updates that are triggered from a Rive event will need to be manually marked to run on the UI thread using runOnUiThread. See examples below.

Opening a URL

Events of type OpenUrlRiveEvent will not automatically open links. The code needs to be added manually in your project.
The following is an example that demonstrates how to open a URL on Android when an OpenUrlRiveEvent is received:
val eventListener = object : RiveFileController.RiveEventListener {
    override fun notifyEvent(event: RiveEvent) {
        when (event) {
            is OpenURLRiveEvent -> {
                runOnUiThread {
                    try {
                        val uri = Uri.parse(event.url);
                        val browserIntent =
                            Intent(Intent.ACTION_VIEW, uri)
                        startActivity(browserIntent)
                    } catch (e: Exception) {
                        Log.i("RiveEvent", "Not a valid URL ${event.url}")
                    }
                }
            }
        }
    }
}
yourRiveAnimationView.addEventListener(eventListener);
You can also access event.target to get the target destination of the URL, as set in the editor.

Example

The following demonstrates how to update UI in response to some Rive event (named “StarRating”) that contains a custom number property (named “Rating”). Note the runOnUiThread:
val eventListener = object : RiveFileController.RiveEventListener {
    override fun notifyEvent(event: RiveEvent) {
        when (event) {
            is GeneralRiveEvent -> {
                runOnUiThread {
                    // This event contains a number value with the name "rating"
                    // to indicate the star rating selected
                    if (event.name == "StarRating" && event.properties.containsKey("rating")) {
                        starRatingTextView.text = "Star rating: ${event.properties["rating"]}"
                    }
                }
            }
        }
    }
}
It’s possible to evaluate which event has come through by checking the name and type of event (GeneralRiveEvent vs OpenURLRiveEvent). By calling event.properties you’ll get a HashMap that contains any custom properties defined on the event.

Additional Resources