f4e6"><pre>// Load <span class="hljs-keyword">the</span> animation <span class="hljs-built_in">file</span> <span class="hljs-built_in">from</span> <span class="hljs-keyword">the</span> bundle, note that you could also</pre></div><div id="8dc8"><pre><span class="hljs-comment">// download this. The RiveFile just expects a list of bytes.</span></pre></div><div id="2f73"><pre>rootBundle<span class="hljs-selector-class">.load</span>(riveFileName)<span class="hljs-selector-class">.then</span>(</pre></div><div id="1dd8"><pre>(<span class="hljs-meta">data</span>) async {</pre></div><div id="8d20"><pre>// Load <span class="hljs-keyword">the</span> RiveFile <span class="hljs-built_in">from</span> <span class="hljs-keyword">the</span> binary data.</pre></div><div id="2318"><pre><span class="hljs-keyword">final</span> <span class="hljs-keyword">file</span> = RiveFile.<span class="hljs-keyword">import</span>(<span class="hljs-keyword">data</span>);</pre></div><div id="fe6a"><pre><span class="hljs-comment">// The artboard is the root of the animation and gets drawn in the</span></pre></div><div id="dca0"><pre><span class="hljs-comment">// Rive widget.</span></pre></div><div id="91dd"><pre>final artboard <span class="hljs-operator">=</span> file.mainArtboard<span class="hljs-comment">;</span></pre></div><div id="2f9c"><pre>// Add <span class="hljs-selector-tag">a</span> controller <span class="hljs-selector-tag">to</span> play back <span class="hljs-selector-tag">a</span> known <span class="hljs-attribute">animation</span> on the <span class="hljs-selector-tag">main</span>/default</pre></div><div id="7a87"><pre>// artboard. We store <span class="hljs-keyword">a</span> reference <span class="hljs-built_in">to</span> <span class="hljs-keyword">it</span> so we can toggle playback.</pre></div><div id="9524"><pre><span class="hljs-variable">artboard.addController</span>(<span class="hljs-variable">_controller</span> = <span class="hljs-function"><span class="hljs-title">SimpleAnimation</span>(<span class="hljs-string">'Animation 1'</span>));</span></pre></div><div id="6de6"><pre>// need <span class="hljs-keyword">to</span> <span class="hljs-keyword">start</span> <span class="hljs-keyword">with</span> <span class="hljs-keyword">false</span> so controller <span class="hljs-keyword">is</span> paused</pre></div><div id="763b"><pre>_controller!<span class="hljs-string">.isActive</span> = <span class="hljs-literal">false</span>;</pre></div><div id="737d"><pre>setState(() <span class="hljs-operator">=</span>> _riveArtboard <span class="hljs-operator">=</span> artboard)<span class="hljs-comment">;</span></pre></div><div id="d97d"><pre>},</pre></div><div id="ce77"><pre>)<span class="hljs-comment">;</span></pre></div><p id="b7f5">The way to read that is that we are loading the riv file through the rootBundle function which returns a future and we do not need to add onError as we are already using the catcher plugin to catch app exceptions. But, we need to be careful here as according to the source of SimpleAnimation nothing is thrown if unable to load the file.</p><p id="4b67">Or to put it another way, we have to audit-the-chain-of-custody. In other words, work up from the process of loading the file. I know that rootBundle function will return an onError future if an error occurs. That will basically be caught by the catcher plugin code in the main function.</p><p id="03df">And, before the rootBundle we have the two exceptions that the rive player will which is either a format error or unsupported version. In fact, this is why you should always name your riv files by the runtime version in the case when the-rive player changes formats.</p><p id="85a9">This is the basic strategy you have to use to ensure you track down and catch every exception in your flutter application code.</p><h1 id="c0e7">The Artboard and SimpleAnimation Controller</h1><p id="baad">An artboard is an animation itself. There can be more than one artboard. And the artboard name is what the Animation Controller needs to grab the animation. In this code case, Animation 1, is the artboard.</p><p id="d285">The SimpleAnimation Controller needs the artboard to use for animation play-black. In this case, it’s Animation 1. The isActive boolean flag indicates whether that artboard is active being played as an animation. That means we actually should set it to false before setting the artboard state the
Options
first time.</p><p id="7a07">This way the file will load in our widget container as part of the-rive player but not immediately start except when we press the play button.</p><h1 id="ee51">The Source and The Video</h1><p id="b472">The source is at this project repo in the rive_animations subfolder as the stop_start_animation project:</p><p id="4ba2"><a href="https://github.com/fredgrott/flutter_design_and_arch_rosetta">https://github.com/fredgrott/flutter_design_and_arch_rosetta</a></p><p id="fa4d">That repo is where I am putting all my medium article code and the demo apps I am building for my flutter book developer series.</p><p id="29c1">The video of the demo in action is at youtube and embedded here:</p>
<figure id="1458">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F3mfXPtbHgVc%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D3mfXPtbHgVc&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F3mfXPtbHgVc%2Fhqdefault.jpg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=youtube" allowfullscreen="" frameborder="0" height="480" width="854">
</div>
</div>
</figure></iframe></div></div></figure><h1 id="dea4">Conclusion</h1><p id="8543">As I go further into rive animations I will be covering how to use them for background candy in login-screens,</p><p id="323b">buttons on the appbar, buttons in bottom navbar navigation, and other neat stuff to help you brand your flutter application. And, yes, some advanced stuff I will cover includes how to integrate the animation controllers with the state management solutions out there such as riverpod, provider, getit, getx, and mobx.</p><h1 id="f540">Resources</h1><p id="1a5e">Resources specific to the article:</p><p id="2d67">Rive plugin at pub.dev https://pub.dev/packages/rive</p><p id="f97d">rive studio app to edit animations https://rive.app/</p><p id="a186">rive flutter source code https://github.com/rive-app/rive-flutter</p><p id="6896">flutter design and arch rosetta <a href="https://github.com/fredgrott/flutter_design_and_arch_rosetta">https://github.com/fredgrott/flutter_design_and_arch_rosetta</a></p><p id="c5c6">General Flutter and Dart resources:</p><p id="a255">Flutter Community Resources https://flutter.dev/community</p><p id="33b2">Flutter SDK https://flutter.dev/docs/get-started/install</p><p id="2249">Android Studio IDE https://developer.android.com/studio</p><p id="d85f">MS’s Visual Studio Code https://code.visualstudio.com/</p><p id="5684">Flutter Docs https://flutter.dev/docs</p><p id="af9d">Dart Docs https://dart.dev/guides</p><p id="b533">Google Firebase Mobile Device TestLab <a href="https://firebase.google.com/docs/test-lab">https://firebase.google.com/docs/test-lab</a></p><h1 id="79c4">Trademark Notice</h1><p id="f835">Google LLC owns the following trademarks; Dart, Flutter, Android, Roboto, Noto. Apple Inc owns the trademarks iOS, MacOSX, Swift, and Objective-C. Apple Inc owns trademarks to their fonts of SF Pro, Sf Compact, SF mono, and New York. JetBeans Inc owns the trademarks to JetBeans, IntelliJ, and Kotlin. Oracle Inc owns the Java trademark. Microsoft Inc owns the trademarks to MS Windows OS and Powershell. Gradle is a trademark of Gradle Inc. The Git Project owns the trademark to Git. Linux Foundation owns the trademark to Linux. Smartphone OEM’s own trademarks to their mobile phone product names. To the best of my ability, I follow the brand and usage guidelines with the above-mentioned trademarks.</p><h1 id="6d49">About Fred Grott</h1><p id="9d86">I’m the crazy SOB who as a former android mobile developer is starting to write about flutter mobile app development, design, and life(see <a href="https://fredgrott.medium.com/eff-covid-and-the-gop-e912db0548b8">Eff COVID-19 and GOP</a> ). Will I reach the pivotal One Million Medium monthly viewers mark? Sit back and watch. Find me on social platforms such as <a href="https://www.xing.com/profile/Fred_Grott/cv">Xing</a>, <a href="https://www.linkedin.com/in/fredgrottstartupfluttermobileappdesigner/">LinkedIN</a>, <a href="https://keybase.io/fredgrott">Keybase</a>, and <a href="https://twitter.com/fredgrott">Twitter</a>.</p></article></body>
This is an introduction to rive(formerly flare) animations for your flutter application. Why should you use rive?
First, the Adobe After Effects animation files can be loaded and converted by rive studio which also means that the Lottie files site files can also be loaded and converted into riv format by the-rive studio web app. The gist is that it allows you to reduce the number of animation controllers you have write-by-hand.
First, before we get to flutter code on how to use the rive plugin let’s cover some basics about rive. You need the animation-name for your animation controller to use. That name can be found in the web player preview of any animation within the rive web app at:
That is the animation by Bobbeh which I am using in this flutter demo; as you notice the right panel shows the animation-name as Animation 1(the artboard) which will get used in our animation controller.
To install the rive plugin in your pubspec under dependencies:
rive: ^0.7.9
Since, we will be making use of Futures to load the file; I am using catcher to catch application exceptions as it’s easier to catch exceptions. And, that code typically in the main function looks like this:
The logger code is the exact same right from my Logging, the Expert Way Article:
Now we can get down to how to get the rive player to play our animation.
The Rive Controller
First, we create a simple myapp container to insert our my-animation widget into:
I supply two things the catcher navigatorKey so that a full app exception page is displayed when I have an app exception and I use a flag to turn off the debug banner.
There are two things you will always encounter with animation controllers. One, due to null-safety you will initialize the controller last after you set up your togglePlay function and set up any other variables including your artboard variable.
Let’s look at the setup state, initState function:
@override
voidinitState() {
super.initState();
// Load the animation filefromthe bundle, note that you could also
// download this. The RiveFile just expects a list of bytes.
rootBundle.load(riveFileName).then(
(data) async {
// Load the RiveFile fromthe binary data.
finalfile = RiveFile.import(data);
// The artboard is the root of the animation and gets drawn in the
// Rive widget.
final artboard = file.mainArtboard;
// Add a controller to play back a known animation on the main/default
// artboard. We store a reference toit so we can toggle playback.
The way to read that is that we are loading the riv file through the rootBundle function which returns a future and we do not need to add onError as we are already using the catcher plugin to catch app exceptions. But, we need to be careful here as according to the source of SimpleAnimation nothing is thrown if unable to load the file.
Or to put it another way, we have to audit-the-chain-of-custody. In other words, work up from the process of loading the file. I know that rootBundle function will return an onError future if an error occurs. That will basically be caught by the catcher plugin code in the main function.
And, before the rootBundle we have the two exceptions that the rive player will which is either a format error or unsupported version. In fact, this is why you should always name your riv files by the runtime version in the case when the-rive player changes formats.
This is the basic strategy you have to use to ensure you track down and catch every exception in your flutter application code.
The Artboard and SimpleAnimation Controller
An artboard is an animation itself. There can be more than one artboard. And the artboard name is what the Animation Controller needs to grab the animation. In this code case, Animation 1, is the artboard.
The SimpleAnimation Controller needs the artboard to use for animation play-black. In this case, it’s Animation 1. The isActive boolean flag indicates whether that artboard is active being played as an animation. That means we actually should set it to false before setting the artboard state the first time.
This way the file will load in our widget container as part of the-rive player but not immediately start except when we press the play button.
The Source and The Video
The source is at this project repo in the rive_animations subfolder as the stop_start_animation project:
That repo is where I am putting all my medium article code and the demo apps I am building for my flutter book developer series.
The video of the demo in action is at youtube and embedded here:
Conclusion
As I go further into rive animations I will be covering how to use them for background candy in login-screens,
buttons on the appbar, buttons in bottom navbar navigation, and other neat stuff to help you brand your flutter application. And, yes, some advanced stuff I will cover includes how to integrate the animation controllers with the state management solutions out there such as riverpod, provider, getit, getx, and mobx.
Resources
Resources specific to the article:
Rive plugin at pub.dev https://pub.dev/packages/rive
rive studio app to edit animations https://rive.app/
rive flutter source code https://github.com/rive-app/rive-flutter
Google LLC owns the following trademarks; Dart, Flutter, Android, Roboto, Noto. Apple Inc owns the trademarks iOS, MacOSX, Swift, and Objective-C. Apple Inc owns trademarks to their fonts of SF Pro, Sf Compact, SF mono, and New York. JetBeans Inc owns the trademarks to JetBeans, IntelliJ, and Kotlin. Oracle Inc owns the Java trademark. Microsoft Inc owns the trademarks to MS Windows OS and Powershell. Gradle is a trademark of Gradle Inc. The Git Project owns the trademark to Git. Linux Foundation owns the trademark to Linux. Smartphone OEM’s own trademarks to their mobile phone product names. To the best of my ability, I follow the brand and usage guidelines with the above-mentioned trademarks.
About Fred Grott
I’m the crazy SOB who as a former android mobile developer is starting to write about flutter mobile app development, design, and life(see Eff COVID-19 and GOP ). Will I reach the pivotal One Million Medium monthly viewers mark? Sit back and watch. Find me on social platforms such as Xing, LinkedIN, Keybase, and Twitter.