I have been working on a horizontal FlatList in React Native. The idea is, a user can remove the item by clicking on the item. So once the item is removed, I need to :
- Remove the item from the list with a nice opacity animation
- At the same time, I need to fill up space with the next items sliding in to fill it up properly.
At first, I was trying it out with react native Animated library but it was getting messier and I could not achieve the effects that I wanted. However, with LayoutAnimation from react-native, this can be done easily. Letβs start then. First, we will put the initial set up for our horizontal FlatList.
const { height, width } = Dimensions.get("window");
const dummyData = [
{
id: 1,
name: "orange card",
color: "orange",
},
{
id: 2,
name: "red card",
color: "red",
},
{
id: 3,
name: "green card",
color: "green",
},
{
id: 4,
name: "blue card",
color: "blue",
},
{
id: 5,
name: "cyan card",
color: "cyan",
},
];
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingTop: 120,
backgroundColor: "#ecf0f1",
padding: 8,
},
flatList: {
paddingHorizontal: 16,
paddingVertical: 16,
},
cardContainer: {
height: 100,
width: width * 0.5,
marginRight: 8,
},
card: {
height: 100,
width: width * 0.5,
borderRadius: 12,
padding: 10,
},
text: { color: "white", fontWeight: 'bold' }
});
export default function App() {
const [data, setData] = React.useState(dummyData);
return (
<View style={styles.container}>
<FlatList
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.flatList}
horizontal={true}
data={data}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => {
return (
<TouchableOpacity
style={styles.cardContainer}
onPress={() => removeItem(item.id)}
>
<Card style={[styles.card, {backgroundColor: item.color}]}>
<Text style={styles.text}>{item.name}</Text>
</Card>
</TouchableOpacity>
);
}}
/>
</View>
);
}
With this, we get the following output.
Now it is time for removing the item from the FlatList, we can just pass the id of the item to our FlatList and remove the items that match the id. Like so:
const removeItem = (id) => {
let arr = data.filter(function(item) {
return item.id !== id
})
setData(arr);
};
if we click our item, the items will be removed from the FlatList but without any animation. This will like odd. The output will be like the following -
Okay, now let's start the animation. With LayoutAnimation we can easily create a layout config that will have the effect.
const layoutAnimConfig = {
duration: 300,
update: {
type: LayoutAnimation.Types.easeInEaseOut,
},
delete: {
duration: 100,
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.opacity,
},
};
const removeItem = (id) => {
let arr = data.filter(function(item) {
return item.id !== id
})
setData(arr);
// after removing the item, we start animation
LayoutAnimation.configureNext(layoutAnimConfig)
};
If we check the config, we can see the animation that we are doing while deleting the item from the list. The type is easeInEaseOut and the property is opacity. So let us see the final result with the LayoutAnimation effect.
One last important thing to note that, ensure your key extractor returns a unique key for each item. Do not return index.toString() in your keyExtractor function of the FlatList. Otherwise, the animation will not work. I was stuck with this for quite a long time. :D
You can check out the full demo here
Top comments (2)
Thanks bro , it helped me a lot ,instead of stack overflow , google recommended me this..
For some reason deleting the odd indexed item(3th in my case) in horizontal FlatList, leaves a gap on Android. After moving the list everything is ok. Any idea why this happend?