Further runtime documentation can be found in Rive's help center.
Rive is a real-time interactive design and animation tool. Use our collaborative editor to create motion graphics that respond to different states and user inputs. Then load your animations into apps, games, and websites with our lightweight open-source runtimes.
This is the Android runtime for Rive, currently in beta. The api is subject to change as we continue to improve it. Please file issues and PRs for anything busted, missing, or just wrong.
To add Rive in your project, include the following in your dependencies
:
implementation 'app.rive:rive-android:0.2.7'
The simplest way to get a rive animation into your application is to include it as part of a layout. The following will include the rive file loaded from the raw resources location, and auto play its first animation.
<app.rive.runtime.kotlin.RiveAnimationView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:riveResource="@raw/off_road_car_blog" />
The animation view can be further customized as part of specifying layout attributes.
fit
can be specified to determine how the animation should be resized to fit its container. The available choices are FILL
, CONTAIN
, COVER
, FIT_WIDTH
, FIT_HEIGHT
, NONE
, SCALE_DOWN
alignment
informs how it should be aligned within the container. The available choices are TOP_LEFT
, TOP_CENTER
, TOP_RIGHT
, CENTER_LEFT
, CENTER
, CENTER_RIGHT
, BOTTOM_LEFT
, BOTTOM_CENTER
, BOTTOM_RIGHT
.
<app.rive.runtime.kotlin.RiveAnimationView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:riveResource="@raw/off_road_car_blog"
app:riveAlignment="CENTER"
app:riveFit="CONTAIN"
/>
Or
animationView.fit = Fit.FILL
animationView.alignment = Alignment.CENTER
Animations can be controlled in many ways, by default loading a RiveAnimationView with a resource file will autoplay the first animation on the first artboard. The artboard and animation can be specified.
<app.rive.runtime.kotlin.RiveAnimationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:riveAutoPlay="true"
app:riveArtboard="Square"
app:riveAnimation="rollaround"
app:riveResource="@raw/artboard_animations" />
Or
animationView.setRiveResource(
R.raw.artboard_animations,
artboardName = "Square",
animationName = "rollaround",
autoplay = true
)
furthermore animations can be controlled later too:
To play an animation named rollaround.
animationView.play("rollaround")
multiple animations can play at the same time, and additional animations can be added at any time
animationView.play(listOf("bouncing", "windshield_wipers"))
When playing animations, the Loop Mode and direction of the animations can also be set per animation.
animationView.play(listOf("bouncing", "windshield_wipers"), Loop.ONE_SHOT, Direction.Backwards)
Similarly animations can be paused, or stopped, either all at the same time, or one by one.
animationView.stop()
animationView.stop("bouncing")
animationView.stop(listOf("bouncing", "windshield_wipers"))
animationView.pause()
animationView.pause("bouncing")
animationView.pause(listOf("bouncing", "windshield_wipers"))
Mixing goes further than just playing multiple animations at the same time, animations can use a mix factor between 0 and 1, to allow multiple animations effects to blend together. The high level views do not expose this currently. but you can wrap your own render loop around the core libraries. The advance function is where you can specify a mix factor
The rive android runtimes allow listener registration, take a look at the events section in the rive player for an example of how this works.
findViewById<RiveAnimationView>(R.id.android_player_view)
val listener = object : Listener {
override fun notifyPlay(animation: LinearAnimationInstance) {
// Do something
}
override fun notifyPause(animation: LinearAnimationInstance) {
// Do something
}
override fun notifyStop(animation: LinearAnimationInstance) {
// Do something
}
override fun notifyLoop(animation: LinearAnimationInstance) {
// Do something
}
}
animationView.registerListener(listener)
Rive allows the artist to set blend modes on shapes to determine how they are to be merged with the rest of the animation.
Each runtime is supporting the various blend modes natively, this means that there are some discrepancies in how blend modes end up being applied, we have a test file that is shipped inside the application that highlights the differences.
For android, devices running sdk < 29 do not support a number of blend modes, there are also issues modes are combined with transparency as the examples highlight.
Original | SDK <29 | SDK 29+ |
---|---|---|
Yes, animations are applied in order. Animations animate a property of a shape from one position to another. If multiple animations are playing that are setting the same property on the same shape, only the last applied change will be visible.
The way past this and into some pretty cool effects will take you to mixing, where multiple animations are applied partially. The RiveView & RiveDrawable do not provide options to set mixing values though, so to take advantage of this, you will need to run your own render loop. you can still use the core parts of this library to interact with rive files though!
This is the main module of the android library, you can find a useful RiveAnimationView
or RiveDrawable
in the app.rive.runtime.kotlin
namespace.
The underlying c++ runtimes is mapped to objects in the app.rive.runtime.kotlin.core
namespace. This can be used to allow for more fine grained control for more complex animation loops. Our high level views are simply built on top of this.
Multiple sample activities can be found here, this can be a useful reference for getting started with using the runtimes.
The runtimes are built on top of our c++ runtimes. these are included as a submodule in /submodules. The /cpp
folder contains the c++ side of our bindings into android.
If you have changed the cpp submodule, or if you have made changes to the cpp bindings, you will need to rebuild the cpp runtimes to generate the new .so files.
cd cpp
./build.rive.for.sh -c -a x86
./build.rive.for.sh -c -a x86_64
./build.rive.for.sh -c -a arm64-v8a
./build.rive.for.sh -c -a armeabi-v7a
Rive needs to initialize its runtime when your app starts. It includes an initializer that does this for you automatically. The initialization provider is set up in the Rive module's manifest.
Gradle will typically merge up the module's manifest with your app's so you don't have to do anything. If you're using another build system, this might not happen.
If that's the case, you can activate this by either including a provider in your manifest file:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="app.rive.runtime.kotlin.RiveInitializer"
android:value="androidx.startup" />
</provider>
or calling the initializer in your code:
AppInitializer.getInstance(applicationContext)
.initializeComponent(RiveInitializer::class.java)
You'll need the add a dependency for Jetpack Startup:
dependencies {
implementation "androidx.startup:startup-runtime:1.0.0"
}
To update the documentation, run the rive-android:kotlin [dokkaGfm]
task.
And then replace the contents of docs with the newly generated output
rm -rf docs/gfm
mv kotlin/build/dokka/gfm docs
(autogenerated) API documentation can be found here