Even with all the information contained in this book, some questions may arise when using Lottie-based animations in our React Native apps. In this chapter, we will go over some of the most commonly asked questions by developers when it comes to lottie-react-native usage. For convenience, the following is the list of questions and issues you will find in the following pages:
There are a number of effects in Adobe After Effects that are not supported on certain platforms. When this kind of error happens, it's best to go to the list of supported effects in Lottie's documentation at https://github.com/airbnb/lottie/blob/master/supported-features.md.
Take into account that this list may change over time, as Lottie is being constantly improved. As the list shows, the same effect may show on a specific platform but might be missing on a different one.
The most common approaches for these cases are to remake the animation, remove the selected effect, or create a different animation for the failing platform, as there is no programmatic solution for this problem.
Check that the JSON file containing the animation is placed within the React Native app project folder structure and is reachable through an import/require statement in the component in which the animation should be rendering. To test this, you can console.log the contents of the JSON file; if they log as undefined, it means that the file was not reachable by the component:
const animation = require('./assets/animations/loadingBar.json')
console.log(animation)
In this case, you might want to move the JSON file to a different folder or try with a different JSON file, as it's possible the file was damaged or inconsistent. Using a JSON linter can help to identify and fix this kind of issue.
LottieView inherits its size behavior from the standard React Native View component, and therefore, it can be changed through the style property on its containing parent. If the image size looks wrong, try first explicitly changing the parent's size:
<View style={{width: 300, height: 150}}>
<LottieView
ref={animation}
source={require('./assets/animations/loadingBar. json')}
loop={false}
/>
</View>
If that didn't work, try changing width or height explicitly in the LottieView component:
<LottieView
ref={animation}
source={require('./assets/animations/loadingBar. json')}
loop={false}
style={{width: 300, height: 150}}
/>
Parent-relative sizes (percentages) can also be used in both approaches. Always be aware of the parent size, as many issues can be fixed by making sure the parent size is correct. Also, take into consideration using the flex property if needed.
There are several approaches to this issue:
The simplest approach to achieve reverse playback is to use the speed prop on the LottieView component, as negative values will make the animation play backward. If you want to play the animation in reverse but at its original speed, you need to set the speed prop to –1, but you can also play it at double speed by setting it to –2 or half-speed by changing it to –0.5:
<LottieView
source={require('./assets/animations/loadingBar.json')}
speed={-1}
/>
If you are using the animated API to control the progress of your animation, you can use methods such as Animated.timing, and make sure you are passing descending values:
// start animation at frame 300 and go decrementally to frame 0
const progress = useMemo(() => new Animated.Value(300), []);
useEffect(() => {
Animated.timing(progress, {
toValue: 0,
duration: 500,
useNativeDriver: true,
easing: Easing.linear,
}).start();
}, [downloadedFiles, progress]);
return (
<SafeAreaView>
<View style={styles.container}>
<LottieView
source={require('./assets/animations/loadingBar. json')}
progress={progress}
/>
</View>
</SafeAreaView>
);
The newest versions of lottie-react-native can only be used on AndroidX projects. This means that if your app hasn't been migrated to AndroidX (https://developer.android.com/jetpack/androidx), it won't be able to display any Lottie animations.
In this case, you can try older versions of lottie-react-native. For example, try running the following:
yarn add [email protected]
yarn add [email protected]
Take into account that for these cases, the API might be different or some extra installation steps might be required. Always check the version-specific documentation when using older versions of lottie-react-native.
lottie-react-native requires some extra installation steps for it to work properly:
The most common building issue for lottie-react-native in iOS has to do with the lack of support for React Native projects with Swift libraries. In this case, you need to create a Swift bridging header in order to get your app ready for Swift libraries:
You may need to rebuild your project for the changes to take effect. Once this is done, lottie-react-native should be ready to display your animation on iOS.
Older versions of Lottie have rendering issues and won't work properly with newer versions of Android and iOS. To fix this kind of issue, make sure you have the most adequate lottie-react-native version for the platform version you are running your app in.
You can find a list of available versions for lottie-react-native in the projects repository (https://github.com/lottie-react-native/lottie-react-native) or the npm site (https://www.npmjs.com/package/lottie-react-native).
This is often not a problem with lottie-react-native but with the way Bodymovin exports colors. You may still be able to fix this problem by manually going through your JSON file and manually modifying them.
Layer colors in the JSON file usually are defined by the key named "sc", so you can search for that key and change the hex value for the color you want to change. For example, if you expect a red color but you are getting a white one, you can search for "sc":"#ffffff" and replace it with "sc":"#ff0000".
Take into account that there might be more than one layer with that color defined, so you might need to do trial and error until you find the exact layer you need to change.
Showing a Lottie animation on an app startup is a nice user experience that is becoming more and more popular as mobile apps become more sophisticated. A common approach is to load the animation as the main screen, have a state variable that changes once the animation is finished, and change to the real main screen immediately after most of the initial data has been loaded:
import React, { useState } from 'react';
const App = () => {
const [animationFinished, setAnimationFinished] = useState(false);
useEffect(() => {
loadAppData(); // load initial data
}, []);
if (animationFinished === false) {
return(
<View style={styles.splash}>
<LottieView source={require('./assets/animations/ splashAnimation.json')}
autoPlay
loop={false}
onAnimationFinish={() => {
setAnimationFinished(true);
}}
/>
</View>
)
} else {
return(
<MainScreen />
)
}
};
If we want to display a Lottie animation as a splash screen, we need to put this component as the initial one, so the first thing that the app does is to load this animation. Note how we call loadAppData() when the component is mounted to start loading the initial data, before the component shows that data to the user.
If you created your animation with external assets (images), you need to add those images into your app and let lottie-react-native know where those images can be found. This is done at a native level and requires some configuration, as explained in Chapter 9, Let’s Do Some Magic: Integrating Your First Lottie Animation, in the section named Using Lottie files with assets.
Make sure that you do the following:
LottieView component inherits its layout behavior from the standard View component in React Native, and therefore, centering should be done in the same way we would center View in React Native. This can be done by either using the alignSelf: 'center' key on the style property for the LottieView component or making sure that the parent component has the correct size and uses alignItems: 'center' in its style property.
If this approach didn't work, we should make sure the parent component has the right size, as most of the alignment problems derive from that issue.
The easiest approach would be to use the imperative API and adjust the play() method and the onAnimationFinish prop repeat that plays the animation when its playback is finished:
import React, {useState, useRef} from 'react';
const App = ({}) => {
const animation = useRef(null);
const [numPlaybacks, setNumPlaybacks] = useState(0);
return (
<SafeAreaView>
<View style={styles.container}>
<LottieView
ref={animation}
source={require('./assets/animations/loadingBar. json')}
loop={false}
autoPlay
onAnimationFinish={() => {
if (numPlaybacks + 1 < maxNumPlaybacks) {
animation.current.play();
setNumPlaybacks(numPlaybacks + 1);
}
}}
/>
</View>
</SafeAreaView>
);
};
The key in this piece of code is how onAnimationFinish is used to repeat the animation, controlling the number of times through a state variable (numPlaybacks) and a constant maximum number of repetitions (maxNumPlaybacks).
As mobile operating systems evolve, they use different graphic rendering techniques. Lottie adapts to those changes by releasing new versions periodically that improve the performance of the animations rendered. It's important to always use the latest version of lottie-react-native because it may contain performance improvements based on the latest rendering engines for Android and iOS devices.
React Native also offers an out-of-the-box performance improvement for the animated API by accepting the useNativeDriver parameter, which leverages the native capabilities of some UI components. Using this parameter may help when using Animated combined with lottie-react-native.
If you want to ensure that you are using the latest version of lottie-react-native, make sure you check the README documentation in the lottie-react-native repository, following its installation guidelines.
lottie-react-native allows developers to use the colorFilters property in any LottieView component with the intention of changing the colors for specific layers in an animation. The names for those layers are defined in After Effects and stored in the exported JSON Lottie file, such as in the following code block:
import React from 'react';
import LottieView from 'lottie-react-native';
import {SafeAreaView, View} from 'react-native';
const App = ({}) => {
return (
<SafeAreaView>
<View style={{width: '100%', height: '100%'}}>
<LottieView
source={require('./assets/animations/loadingBar. json')}
autoPlay
colorFilters={[
{
keypath: 'border',
color: '#FF0000',
},
{
keypath: 'bar',
color: '#FF0000',
},
]}
/>
</View>
</SafeAreaView>
);
};
export default App;
In this example, we are changing the colors for two layers named border and bar to be fully red.
The simplest approach would be to use fetch() to download the JSON file, parse it, and set it in a state variable so that it can be used as a source prop in a LottieView container:
import React, {useState, useEffect} from 'react';
import LottieView from 'lottie-react-native';
import {SafeAreaView, View} from 'react-native';
const App = ({}) => {
const [animation, setAnimation] = useState();
useEffect(() => {
fetch('https://myserver.com/animation.json', {
method: 'GET',
})
.then(response => response.json())
.then(responseJSON => {
setAnimation(responseJSON);
})
.catch(e => console.error(e));
}, []);
return (
<SafeAreaView>
<View style={{width: '100%', height: '100%'}}>
{animation && <LottieView source={animation} autoPlay loop />}
</View>
</SafeAreaView>
);
};
export default App;
If this approach is followed, it's important to control the LottieView component until the animation is fully downloaded (animation && <LottieView).
Several users have reported crashes on Android due to errors. The latest versions of React Native have refined this process, and updating these should fix the issue, but if this is not a possibility, you can manually link the required libraries as follows:
Now, you should rebuild your app and find it is not crashing anymore.
This is a common error among React Native developers when having to deal with native code in iOS. The problem is related to changes in the dependencies tree that ended up rearranging which library depends on another. Therefore, the easiest solution is to reset the dependencies tree in our iOS project, ensuring that we end up with a clean dependency chain.
To achieve this, we can clean our builds folder by pressing Command + Shift + K on Xcode and then rebuilding the app, by pressing the play button on Xcode or running yarn ios on the command line while being in the project folder.
This error may arise after updating to a newer version of React Native and running the app on an Android device for the first time. Sometimes, just cleaning the builds folder fixes this problem, but there are two other approaches that may fix it if cleaning didn't do the trick:
Thank you for reading through this final chapter, in which we presented the most common questions and issues reported when working with lottie-react-native. There are many other infrequently asked questions that can be found in the lottie-react-native repository issues (https://github.com/lottie-react-native/lottie-react-native/issues) and on Stack Overflow, so make sure that you turn to those resources if you find yourself in need of more specific answers.
20. An error shows on my app – Execution failed for task ':lottie-react-native:compileDebugJavaWithJavac'