react-native-reanimated icon indicating copy to clipboard operation
react-native-reanimated copied to clipboard

Layout animation doesn't work with FlatList

Open Pietro-Putelli opened this issue 3 years ago • 14 comments

Reanimated version: 2.3.0 When I try to use FlatList instead of ScrollView, as shown in the tutorial below, the Layout.springify() doesn't work. https://docs.swmansion.com/react-native-reanimated/docs/tutorials/LayoutAnimations/layoutAnimations

Someone suggests to apply this path: https://patch-diff.githubusercontent.com/raw/piaskowyk/react-native/pull/1.patch. How can I apply the patch? Is there an alternative solution?

Thank you

Pietro-Putelli avatar Dec 13 '21 14:12 Pietro-Putelli

Issue validator

The issue is invalid!

  • Section required but not found: description(for label 🐞 bug)
  • Section required but not found: expected behavior(for label 🐞 bug)
  • Section required but not found: actual behavior & steps to reproduce(for label 🐞 bug)
  • Section required but not found: package versions(for label 🐞 bug)

github-actions[bot] avatar Dec 13 '21 14:12 github-actions[bot]

I believe this is what itemLayoutAnimation is supposed to be for on Reanimated2's version of FlatList: https://github.com/software-mansion/react-native-reanimated/blob/main/src/reanimated2/component/FlatList.tsx#L26

So I'd expect something like this to work (instead of the Animated.ScrollView):

<Animated.FlatList
        data={participantList}
        keyExtractor={p => p.id}
        style={[{width: '100%'}]}
        itemLayoutAnimation={Layout.springify()}
        renderItem={({item: participant}) => {
          return (
            <Participant
              name={participant.name}
              onRemove={() => removeParticipant(participant.id)}
            />
          )
        }}
      />

However, I'm getting the same behavior as a normal FlatList- which is there's no springify on the position of the items when adding/removing.

DigitalZebra avatar Dec 13 '21 21:12 DigitalZebra

Same here

andresribeiro avatar Dec 15 '21 22:12 andresribeiro

I believe this is what itemLayoutAnimation is supposed to be for on Reanimated2's version of FlatList: https://github.com/software-mansion/react-native-reanimated/blob/main/src/reanimated2/component/FlatList.tsx#L26

So I'd expect something like this to work (instead of the Animated.ScrollView):

<Animated.FlatList
        data={participantList}
        keyExtractor={p => p.id}
        style={[{width: '100%'}]}
        itemLayoutAnimation={Layout.springify()}
        renderItem={({item: participant}) => {
          return (
            <Participant
              name={participant.name}
              onRemove={() => removeParticipant(participant.id)}
            />
          )
        }}
      />

However, I'm getting the same behavior as a normal FlatList- which is there's no springify on the position of the items when adding/removing.

Ah turns out this code works on iOS, but not on Android - so seems like this is an Android only issue.

DigitalZebra avatar Dec 16 '21 01:12 DigitalZebra

Layout animation does not work on iOS either correctly. All the animations do only work as long as the Flatlist Item which you try to add or remove is not in the overflowed area. As soon as your element is in a overflowed (eg hidden segment), the animations do not trigger on them. When my list shrinks or I remove elements at an index where the item is not overflowed, the animation works. (at least on iOS)

hirbod avatar Jan 16 '22 20:01 hirbod

I can now confirm, that react native reanimated 2.3.0 works with the code I’ve initially published. Thank you, all the software mansion developers for the best react-native library.

On 16 Jan 2022, at 9:26 PM, Hirbod @.***> wrote:

Layout animation does not work on iOS either correctly. All the animations do only work as long as the Flatlist Item which you try to add or remove is not in the overflowed area. As soon as your element is in a overflowed (eg hidden segment), the animations do not trigger on them. When my list shrinks or I remove elements at an index where the item is not overflowed, the animation works. (at least on iOS)

— Reply to this email directly, view it on GitHub https://github.com/software-mansion/react-native-reanimated/issues/2737#issuecomment-1013946285, or unsubscribe https://github.com/notifications/unsubscribe-auth/APL4WSMM5OHGLORW3ZOHIADUWMSYJANCNFSM5J6ISNKA. You are receiving this because you authored the thread.

Pietro-Putelli avatar Jan 16 '22 21:01 Pietro-Putelli

Hi! It's recommended to use FlatList exported from react-native-reanimated it should also solve the problem.

j-piasecki avatar Jan 28 '22 10:01 j-piasecki

Not working for android :( ig it's better to just use ScrollView instead :disappointed: anyway I will still wait for better support

tarikko avatar Feb 08 '22 15:02 tarikko

Same bug.

"react-native-reanimated": "^2.4.1",

const DATA = Array(10)
  .fill(1)
  .map((_, index) => index + 1);

<Animated.FlatList
        data={data}
        style={{flex: 1}}
        renderItem={({item}) => (
          <Animated.View
            key={item}
            entering={FadeIn}
            exiting={FadeOut}
            layout={Layout.delay(100)}
            style={styles.listItem}>
            <Text>{item}</Text>
          </Animated.View>
        )}
      />

https://user-images.githubusercontent.com/33916400/157805089-cc2dc2f9-4122-4def-80ba-62e1b361bc8e.mov

000xuandu avatar Mar 11 '22 05:03 000xuandu

Any updates on this?

arunim2405 avatar Mar 11 '22 15:03 arunim2405

You need to use the itemLayoutAnimation prop on the Animated.FlatList:

// put this outside of render code
const layout = Layout.springify()

<Animated.FlatList 
  itemLayoutAnimation={layout}
/>

nandorojo avatar Mar 24 '22 19:03 nandorojo

You need to use the itemLayoutAnimation on the Animated.FlatList:

// put this outside of render code
const layout = Layout.springify()

<Animated.FlatList 
  itemLayoutAnimation={layout}
/>

If you can make a demo, then that would be awesome.

tarikko avatar Mar 24 '22 20:03 tarikko

You need to use the itemLayoutAnimation prop on the Animated.FlatList:

// put this outside of render code
const layout = Layout.springify()

<Animated.FlatList 
  itemLayoutAnimation={layout}
/>

This doesn't work for me. I'm still getting no animations on a Flatlist View with numColumns={2}

agoyal0422 avatar Apr 29 '22 22:04 agoyal0422

Bumping this issue - problem persists across both iOS and Android, even when using the above suggested, elsewhere suggested, and combinations of each.

kevindingens avatar Aug 10 '22 13:08 kevindingens

This is still an issue, a very serious problem may add. I'm using Reanimated 3-rc and nothing works, I read like a dozen of issues and non of them fix this problem.

hadnet avatar Oct 16 '22 03:10 hadnet

do you have any news? I code on my android device and when i delete item from array, animation don't work

bi885895 avatar Oct 18 '22 00:10 bi885895

I am seeing this issue as well

eprice122 avatar Oct 19 '22 23:10 eprice122

same here

YounesKHENIFER avatar Nov 01 '22 17:11 YounesKHENIFER

You can make entering and exciting animations by wrapping your ListItem in Animated.View, or put it inside the ListItem component: const renderItem = ({ item }) => ( <Animated.View entering={BounceInLeft} exiting={BounceOutRight}> <PostItem item={item} /> </Animated.View> ) Entering animation works for me on both Android and IOS, but the existing animations still not working. P.S. it works with classic FlatList don't need to import FlatList from Reanimated.

milanp93 avatar Nov 15 '22 18:11 milanp93

This issue still exists 😞

km5x2 avatar Dec 12 '22 03:12 km5x2

Still a thing

shedworth avatar Feb 15 '23 14:02 shedworth

get the same issue as well

amaurycoudr avatar Mar 10 '23 15:03 amaurycoudr

You can make entering and exciting animations by wrapping your ListItem in Animated.View, or put it inside the ListItem component: const renderItem = ({ item }) => ( <Animated.View entering={BounceInLeft} exiting={BounceOutRight}> <PostItem item={item} /> </Animated.View> ) Entering animation works for me on both Android and IOS, but the existing animations still not working. P.S. it works with classic FlatList don't need to import FlatList from Reanimated.

Hi everyone, entering and exiting animations are not enough for list items animation's harmony and itemLayoutAnimation is not working with createAnimatedComponent function. Therefore, you should override the CellRendererComponent property of the animated list, see the example below for an animated flatlist, it is working fine on both Android and iOS.

import * as React from 'react';
import { FlatList } from 'react-native';

const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);

// you can use it to create a section list e.g: 
// const AnimatedSectionList = Animated.createAnimatedComponent(SectionList);


function App() {
  const [items, setItems] = React.useState<Array<any>>([]);

  const renderItem = React.useCallback(
    ({ item }: any) => (
      <TouchableOpacity
          activeOpacity={0.9}
          onPress={() => {
            setItems(prevState => prevState.filter((i: number) => i !== item));
          }}>
          <View style={{height:100, marginVertical: 12, backgroundColor: "red" }}>
            <Text style={{ color: "white", fontSize: 18}}>
              {item}
            </Text>
          </View>
      </TouchableOpacity>
    ),
    [],
  );

  const onPress = React.useCallback(() => {
    setItems(prevState => {
      return [Date.now(), ...prevState];
    });
  }, []);

  const keyExtractor = React.useCallback((item: any) => {
    return item.toString();
  }, []);

  const renderCell = React.useCallback(
    (props: any) => (
      <Animated.View
         {...props}
          layout={Layout.springify()}
          entering={ZoomIn}
          exiting={ZoomOut}/>
    ),
    [],
  );

  return (
    <View style={{flex:1}} >
      <Button title="ADD ITEM" onPress={onPress} />
      <AnimatedFlatList
        contentContainerStyle={{ paddingHorizontal: 24 }}
        data={items}
        renderItem={renderItem}
        keyExtractor={keyExtractor}
        CellRendererComponent={renderCell}
      />
    </View>
  );
}

Here is visual results:

Android iOS

fakhergh avatar Apr 26 '23 13:04 fakhergh

@fakhergh thanks for sharing. I've just tried it with new expo project and

    "react-native-reanimated": "~2.14.4"

iOS is working just fine. Android isn't working. What version are you using?

dimaportenko avatar Apr 26 '23 17:04 dimaportenko

@fakhergh I tried implementing CellRendererComponent while using reanimated: 2.14.4 but I didn't work on my project so I just copied and pasted your code and It didn't work again, can You share your package.json?

NanddoSalas avatar May 06 '23 05:05 NanddoSalas

any update? Same problem here https://snack.expo.dev/@fukemy/chat-reanimated-sample?platform=ios

fukemy avatar May 09 '23 15:05 fukemy

Hi, which version reanimated you used? This code work for ios, but not working with Android

fukemy avatar May 09 '23 15:05 fukemy

From my smoke test, it works on the version

"react-native-reanimated": "^3.1.0"

dimaportenko avatar May 09 '23 19:05 dimaportenko

Same issue with FlatList, no animation on Android or iOS.

aurangs7 avatar Jul 12 '23 06:07 aurangs7

@dimaportenko can u share piecies of code that you make the animation work?

fukemy avatar Jul 12 '23 06:07 fukemy