I was trying to create a collapse animationusing LayoutAnimation from React Native and I saw some topics that this was not working only on android devices. To make it possible, it was necessary to put the following code inside a constructor:
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental
&& UIManager.setLayoutAnimationEnabledExperimental(true);
}
As I'm using functional component, I put this code inside a useEffect without dependecies. However, the animation still not working. Am I doing something wrong or I need to do something more?
My code:
const Collapse = ({ item, onPress }: CollapseProps) => {
const [layoutHeight, setLayoutHeight] = useState<null | number>(0);
useEffect(() => {
if (item.isExpanded) {
setLayoutHeight(null);
} else {
setLayoutHeight(0);
}
}, [item.isExpanded]);
return (
<View>
<TouchableOpacity onPress={onPress}>
<Text>{item.title}</Text>
</TouchableOpacity>
<View
style={{
overflow: 'hidden',
height: layoutHeight,
}}>
{item.data.map((element: any) => (
<Text>{element.text}</Text>
))}
</View>
</View>
);
};
const Menu = () => {
const [menuMock, setMenuMock] = useState(mockMenu);
useEffect(() => {
if (Platform.OS === 'android') {
// eslint-disable-next-line no-unused-expressions
UIManager.setLayoutAnimationEnabledExperimental
&& UIManager.setLayoutAnimationEnabledExperimental(true);
}
}, []);
const updateLayout = (index: number) => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
const arrOfMenuMock = [...menuMock] as any;
arrOfMenuMock[index].isExpanded = !arrOfMenuMock[index].isExpanded;
// setIsDataOpen(true);
setMenuMock(arrOfMenuMock);
};
return (
<Menu>
{menuMock.map((item, key) => (
<Collapse item={item} key={key} onPress={() => updateLayout(key)} />
))}
</Menu>
)
}
CodePudding user response:
Move LayoutAnimation.configureNext
before change state
useEffect(() => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
if (item.isExpanded) {
setLayoutHeight(null);
} else {
setLayoutHeight(0);
}
}, [item.isExpanded]);
CodePudding user response:
Update: the code should not be in the useEffect, but above the components.
if (Platform.OS === 'android') {
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
The documentation of LayoutAnimation recommends doing this