Home > Software engineering >  How to animate only the currently visible item, instead of other hidden items in FlatList horizontal
How to animate only the currently visible item, instead of other hidden items in FlatList horizontal

Time:09-22

Currently, using FlatList to render items via horizontal pagination where only one view is visible on screen at a time, but when I pass the 'Animated.View' into [renderItem] of FlatList, whenever the currently visible item is clicked on for animation, it also animates all the other hidden views in background so to optimize performance, I tried assigning unique refs as below

  //renderItem
  const Slide = ({item, index}) => {
    const paginatedRefs = {}; //adding an object since we need more than one ref({})

    //Animated.View here is using -import 'Animated' from react-native
    return (
      <View
        ref={(ref) => (
          (paginatedRefs.current[item.id] = ref),
          console.log(paginatedRefs[item.id], item.id)
        )}>
        <Animated.View
          style={[
            animatedStyles.hidden,
            rotateFront, //interpolated settings
          ]}>
          <FlipCard inputRef={frontRef} item={item} />
        </Animated.View>
        <Animated.View
          style={[
            [
              animatedStyles.hidden,
              animatedStyles.back,
              rotateBack, //interpolated settings
            ],
          ]}>
          <FlipCard inputRef={backRef} item={item} />
        </Animated.View>
        <View>
          <Text onPress={doAFlip}>Flip</Text>
        </View>
      </View>
      ); 

My question now is how can I set the styles of 'rotateFront/rotateBack' dynamically on current visible item or is there a more efficient alternative approach towards solving such using 'function components'

//function that detects the currently visible item
 const updateCurrentSlideIndex = (e) => {
    //const contentOffsetY = e.nativeEvent.contentOffset.y;
    const contentOffsetX = e.nativeEvent.contentOffset.x;
    const currentIndex = Math.round(contentOffsetX / width);
    setCurrentSlideIndex(currentIndex);
    console.log('current slide', currentIndex);
    //***********
    //trying to link dynamic styling on the currently visible item for individual animation
    //***********
    //paginatedRefs.current.setNativeProps({});
    //let nameOfRef = paginatedRefs.current.getAttribute("data-name");
  };

In addition, this is the config of FlatList

      <View style={styles.bodyContainer}>
        <ScrollView ref={refScroll}>
          <FlatList
            ref={ref}
            data={slides}
            keyExtractor={(item, index) => item.id}
            renderItem={_renderItem}
            pagingEnabled={true}
            horizontal={true}
            onMomentumScrollEnd={updateCurrentSlideIndex}
            showsHorizontalScrollIndicator={false}
            contentContainerStyle={styles.bodyScrollView}
          />
        </ScrollView>
      </View>

Thanks in advance

CodePudding user response:

What I got from your question is you want to animate a view when user clicks on it which is in renderItem of Flatlist. if so you need to make render item as React Component and create ref inside it and when you'll invoke animation using ref within the component it'll animate the only visible item. here is an example of it

const Slide = ({item,index})=> {
const ref = useRef(null);
return (<Animated.View ref = {ref}>
<TouchableOpacity onPress = {()=> {ref.current.animate....}}>
...
</TouchableOpacity>
</Animated.View>
}

As Flatlist expects renderItem to be a function so it'll not accept Slide which is React Component so you need to do something like

<Flatlist
renderItem = {(props)=> <Slide {...props}/>}
..../>
  • Related