question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Layout Animation is not working as expected

See original GitHub issue

Description

Trying out the new LayoutAnimation right after stable 2.3 is released, but Layout Animation is running as expected

Actual behavior & steps to reproduce

  1. When removing the last item from an array, exit animation is not present. This happens in both ScrollView and Animated.FlatList

https://user-images.githubusercontent.com/15872787/145148807-169b8dc5-b7be-403b-800b-72bb1176615c.mp4

  1. LayoutAnimation is not working in Animated.FlatList #2674

https://user-images.githubusercontent.com/15872787/145149061-3061acae-4fcf-469e-a67d-5bb75461db96.mp4

Expected behavior

  1. Should have an exit animation
  2. LayoutAnimation should be working in Animated.FlatList?

Snack or minimal code example

The implementation is basically copy paste from participant list example
import React, {useState} from 'react';
import {
  Button,
  View,
  Text,
  ScrollView,
  TextInput,
  SafeAreaView,
} from 'react-native';
import Animated, {
  Layout,
  LightSpeedInLeft,
  LightSpeedOutLeft,
} from 'react-native-reanimated';

function Participant({name, onRemove}) {
  return (
    <Animated.View
      style={[styles.participantView]}
      entering={LightSpeedInLeft}
      exiting={LightSpeedOutLeft}
      layout={Layout.springify()}>
      <Text>{name}</Text>
      <Button title="Remove" color="red" onPress={onRemove} />
    </Animated.View>
  );
}

const App = () => {
  const [inputValue, setInputValue] = useState('Reanimated');
  const [participantList, setParticipantList] = useState([]);

  const addParticipant = () => {
    setParticipantList(
      [{name: inputValue, id: Date.now().toString()}].concat(participantList),
    );
  };

  const removeParticipant = id => {
    setParticipantList(
      participantList.filter(participant => participant.id !== id),
    );
  };

  const renderParticipant = React.useCallback(({item: participant}) => {
    const removeParticipant2 = () => {
      setParticipantList(prev => {
        return prev.filter(prevPar => prevPar.id !== participant.id);
      });
    };
    return (
      <Participant
        key={participant.id}
        name={participant.name}
        onRemove={removeParticipant2}
      />
    );
  }, []);

  return (
    <SafeAreaView style={{flex: 1, width: '100%'}}>
      <View style={[styles.listView]}>
        <Text>ScrollView</Text>
        <ScrollView style={[{width: '100%'}]}>
          {participantList.map(participant => (
            <Participant
              key={participant.id}
              name={participant.name}
              onRemove={() => removeParticipant(participant.id)}
            />
          ))}
        </ScrollView>
      </View>

      <View style={styles.listView}>
        <Text>Animated.FlatList</Text>
        <Animated.FlatList
          itemLayoutAnimation={Layout.springify()}
          data={participantList}
          style={[{width: '100%'}]}
          renderItem={renderParticipant}
        />
      </View>

      <View style={[styles.bottomRow]}>
        <View style={[styles.textInput]}>
          <Text>Add participant: </Text>
          <TextInput
            placeholder="Name"
            value={inputValue}
            onChangeText={setInputValue}
          />
        </View>

        <Button
          title="Add"
          disabled={inputValue === ''}
          onPress={addParticipant}
        />
      </View>
    </SafeAreaView>
  );
};

const styles = {
  participantView: {
    borderBottomColor: 'black',
    flex: 1,
    borderBottomWidth: 1,
    padding: 10,
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    backgroundColor: '#fffbeb',
  },
  listView: {
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'space-between',
    width: '100%',
  },
  bottomRow: {
    width: '100%',
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: 10,
  },
  textInput: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
  },
};

export default App;

Package versions

  • React Native: 0.66.3
  • React Native Reanimated: 2.3.0
  • NodeJS:
  • Xcode:
  • Java & Gradle:

Affected platforms

  • Android
  • iOS (not sure)
  • Web (not sure)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:6
  • Comments:7

github_iconTop GitHub Comments

1reaction
lcarrettincommented, Jan 9, 2022

I’m also having this problem, and it seems a clipping issue. When you remove the last item, the items container resizes, clipping the old bounds of the removed view and the animation becomes invisible (or maybe is it even dropped?) A possible workaround could be adding contentContainerStyle={{height: '100%’}} to the properties of the ScrollView or FlatList so the items container wouldn’t resize, but I don’t know if this can cause other issues.

0reactions
juanch0xcommented, Oct 28, 2022

I’m also having this problem, and it seems a clipping issue. When you remove the last item, the items container resizes, clipping the old bounds of the removed view and the animation becomes invisible (or maybe is it even dropped?) A possible workaround could be adding contentContainerStyle={{height: '100%’}} to the properties of the ScrollView or FlatList so the items container wouldn’t resize, but I don’t know if this can cause other issues.

this stops it from scrolling and only keeps it within a certain height

at least for Animated.ScrollView, using contentContainerStyle: {{ flexGrow: 1 }} instead of height: ‘100%’ fix the issue in android

Read more comments on GitHub >

github_iconTop Results From Across the Web

Layout animation not working on first run - Stack Overflow
My problem is, the first time I run the app, when I click on an item, the onClick callback is executed, but the...
Read more >
RecyclerView android:layoutAnimation not working
If you attempt to animate on a view that has not been rendered yet, the animation will occur on the view without a...
Read more >
Animation | Jetpack Compose - Android Developers
Jetpack Compose provides powerful and extensible APIs that make it easy to implement various animations in your app's UI. This document describes how...
Read more >
The little secret of android:animateLayoutChanges
A flag indicating the animation that runs on those items that are changing due to a layout change not caused by items being...
Read more >
keyframes - CSS: Cascading Style Sheets - MDN Web Docs
Properties that can't be animated in keyframe rules are ignored, but supported ... Report problems with this compatibility data on GitHub ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found