LayoutAnimation automatically animates views to their new positions when the next layout happens. A common way to use this API is to call it before calling setState.
On Android, you need to enable LayoutAnimation by setting the following flag in your UIManager:import {UIManager, Platform} from 'react-native';
if (Platform.OS === 'android') {
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
Methods
static configureNext(
config: LayoutAnimationConfig,
onAnimationDidEnd?: () => void,
onAnimationDidFail?: () => void
)
Schedules an animation to happen on the next layout.
Specifies animation properties:Duration of the animation in milliseconds
Configuration for animating in new viewsAnimation type: spring, linear, easeInEaseOut, easeIn, easeOut, or keyboard
Property to animate: opacity, scaleX, scaleY, or scaleXY
Spring damping coefficient (only for spring type)
Configuration for animating views that have been updatedAnimation type: spring, linear, easeInEaseOut, easeIn, easeOut, or keyboard
Spring damping coefficient (only for spring type)
Configuration for animating out removed viewsAnimation type: spring, linear, easeInEaseOut, easeIn, easeOut, or keyboard
Property to animate: opacity, scaleX, scaleY, or scaleXY
Callback called when the animation completes. Guaranteed to be called in Fabric renderer.
Callback called on error. Only called in Fabric renderer if configuration parsing fails.
create()
static create(
duration: number,
type?: string,
property?: string
): LayoutAnimationConfig
Helper for creating a config for configureNext().
Duration of the animation in milliseconds
Animation type: spring, linear, easeInEaseOut, easeIn, easeOut, or keyboard
Property to animate: opacity, scaleX, scaleY, or scaleXY
Preset Methods
easeInEaseOut()
static easeInEaseOut(onAnimationDidEnd?: () => void)
Uses the easeInEaseOut preset (300ms duration, opacity property).
linear()
static linear(onAnimationDidEnd?: () => void)
Uses the linear preset (500ms duration, opacity property).
spring()
static spring(onAnimationDidEnd?: () => void)
Uses the spring preset (700ms duration, spring damping 0.4).
Properties
Types
Available animation types:
LayoutAnimation.Types = {
spring: 'spring',
linear: 'linear',
easeInEaseOut: 'easeInEaseOut',
easeIn: 'easeIn',
easeOut: 'easeOut',
keyboard: 'keyboard',
}
Properties
Available animation properties:
LayoutAnimation.Properties = {
opacity: 'opacity',
scaleX: 'scaleX',
scaleY: 'scaleY',
scaleXY: 'scaleXY',
}
Presets
Pre-configured animation presets:
LayoutAnimation.Presets = {
easeInEaseOut: {...},
linear: {...},
spring: {...},
}
Examples
Basic Usage with setState
import React, {useState} from 'react';
import {View, Button, LayoutAnimation, StyleSheet} from 'react-native';
function BasicExample() {
const [expanded, setExpanded] = useState(false);
const toggleBox = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setExpanded(!expanded);
};
return (
<View style={styles.container}>
<Button title="Toggle" onPress={toggleBox} />
<View
style={[
styles.box,
{width: expanded ? 200 : 100, height: expanded ? 200 : 100}
]}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
backgroundColor: 'blue',
marginTop: 20,
},
});
Custom Configuration
import React, {useState} from 'react';
import {View, Button, LayoutAnimation} from 'react-native';
function CustomAnimation() {
const [width, setWidth] = useState(100);
const animate = () => {
LayoutAnimation.configureNext({
duration: 700,
create: {
type: LayoutAnimation.Types.spring,
property: LayoutAnimation.Properties.scaleXY,
},
update: {
type: LayoutAnimation.Types.spring,
springDamping: 0.4,
},
delete: {
type: LayoutAnimation.Types.linear,
property: LayoutAnimation.Properties.opacity,
},
});
setWidth(width === 100 ? 200 : 100);
};
return (
<View>
<Button title="Animate" onPress={animate} />
<View style={{width, height: 100, backgroundColor: 'blue'}} />
</View>
);
}
With Callbacks
import React, {useState} from 'react';
import {View, Button, LayoutAnimation, Alert} from 'react-native';
function CallbackExample() {
const [size, setSize] = useState(100);
const animateWithCallback = () => {
LayoutAnimation.configureNext(
LayoutAnimation.Presets.spring,
() => {
Alert.alert('Animation Complete!');
},
() => {
Alert.alert('Animation Failed!');
}
);
setSize(size === 100 ? 200 : 100);
};
return (
<View>
<Button title="Animate" onPress={animateWithCallback} />
<View style={{width: size, height: size, backgroundColor: 'blue'}} />
</View>
);
}
Using create() Helper
import React, {useState} from 'react';
import {View, Button, LayoutAnimation} from 'react-native';
function CreateHelper() {
const [height, setHeight] = useState(100);
const animate = () => {
const customAnimation = LayoutAnimation.create(
500,
LayoutAnimation.Types.linear,
LayoutAnimation.Properties.opacity
);
LayoutAnimation.configureNext(customAnimation);
setHeight(height === 100 ? 200 : 100);
};
return (
<View>
<Button title="Animate" onPress={animate} />
<View style={{width: 100, height, backgroundColor: 'blue'}} />
</View>
);
}
List Item Addition/Removal
import React, {useState} from 'react';
import {View, Button, Text, LayoutAnimation, StyleSheet} from 'react-native';
function ListAnimation() {
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const addItem = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setItems([...items, `Item ${items.length + 1}`]);
};
const removeItem = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setItems(items.slice(0, -1));
};
return (
<View style={styles.container}>
<View style={styles.buttons}>
<Button title="Add" onPress={addItem} />
<Button title="Remove" onPress={removeItem} />
</View>
{items.map((item, index) => (
<View key={index} style={styles.item}>
<Text>{item}</Text>
</View>
))}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-around',
marginBottom: 20,
},
item: {
padding: 15,
backgroundColor: '#e0e0e0',
marginVertical: 5,
},
});
Notes
- Call
LayoutAnimation.configureNext() before setState() or other state updates
- On Android, LayoutAnimation must be explicitly enabled via
UIManager
- Fabric renderer provides more reliable callback support
- Works with layout property changes (width, height, position)
- Does not work with transform properties
- Can impact performance with complex layouts or many simultaneous animations