I have flat list horizontal like below , I am trying to add bounce effect when I swipe right and when new item gets visible to the view.

```
const Item = ({ title, image, index }) => (
  <Animatable.View>
    <View style={styles.item}>
      <Text>{title}</Text>
    </View>
  </Animatable.View>
);

const renderItem = ({ item, index }) => (
  <Item title={item.title} image={item.image} index={index} />
);

const [viewableItemsIndices, setViewableItemsIndices] = useState([]);

const handleVieweableItemsChanged = useCallback(
  ({ viewableItems, changed }) => {
    setViewableItemsIndices(viewableItems.map((item) => item.index));
  },
  []
);

const viewabilityConfig = useRef({
  itemVisiblePercentThreshold: 80,
}).current;
return (
  <SafeAreaView style={style.container}>
    <View style={style.flatlistContainer}>
      <FlatList
        snapToInterval={120}
        horizontal={true}
        data={DATA.map((item, i) => {
          item.isViewable = viewableItemsIndices.find((ix) => ix == i);
          return item;
        })}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
        onViewableItemsChanged={handleVieweableItemsChanged}
        viewabilityConfig={viewabilityConfig}
        extraData={viewableItemsIndices}
      />
    </View>
    <Text>Items that should be visible:</Text>
    {viewableItemsIndices.map((i) => (
      <Text> {DATA[i].title}</Text>
    ))}
  </SafeAreaView>
);

```

I have all the visible items in flatlist in **viewableItemsIndices** , now how do I following animatable animation to individual item based on its index..

```
 const AnimationRef = useRef(null);
  const _onPress = () => {
    if(AnimationRef) {
      AnimationRef.current?.bounce();
    }
  }
  return (
    <TouchableWithoutFeedback onPress={_onPress}>
      <Animatable.View ref={AnimationRef}>
        <Text>Bounce me!</Text>
      </Animatable.View>
    </TouchableWithoutFeedback>
  );

```

Edit : Below is complete code

```
import React , { useState, useRef,useCallback } from 'react';
import { SafeAreaView, Image , View, FlatList, StyleSheet, Text, StatusBar } from 'react-native';
import { Ionicons, MaterialCommunityIcons , FontAwesome5 } from "@expo/vector-icons";
import * as Animatable from 'react-native-animatable';
import FlatListWrapper from "../anim/flatwrapper";

const FlatListAnimation = () => {
  const DATA = [
    {
      id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
      title: 'First  Item Item Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/scam_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
      title: 'Second Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/Ramsingh-CharlieA_07062021_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '58694a0f-3da1-471f-bd96-145571e29d72',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6028647473001.jpg'

    },
    {
      id: '58694a0sdsf-3da1-471f-bd96-145571e29d72',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033313370001.jpg'

    },
    {
      id: '58694a0f-3ddsda1-471f-bd96-145571e29d72',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033325319001_v2.jpg'

    },
    {
      id: 'bd7acbea-c1b1-46c2-aed5-3ad531abb28ba',
      title: 'First  Item Item Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/scam_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '3ac68afc-c605-48d3-a4f8-fbd912aa97f63',
      title: 'Second Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/Ramsingh-CharlieA_07062021_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '58694a0f-3da1-471f-bd96-1455371e29d72',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6028647473001.jpg'

    },
    {
      id: '58694a0sdsf-3da1-471f-bd96-1445571e29d72',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033313370001.jpg'

    },
  ];

      const maxlimit = 20;

// Item.js
const Item = (props) => { 
  const {
    item:{image , title, isViewable},
    index
  } = props
  let animation = null
  // set your animation type base on isViewable
  if(isViewable || isViewable == 0){
    animation = ""
  }
  else{
    animation = ""
  }

  return (
    //add animation to Animated.View

<Animatable.View style={style.itemContainer} >

    <Image
      resizeMode="contain"
      style={styles.tinyLogo}
      source={{
        uri: image,
      }}
    />

    </Animatable.View>

  );
}

      const renderItem = ({ item , index }) => (
        <Item title={item.title} image = {item.image} index= {index} />
      );

    // store the indices of the viewableItmes
    const [ viewableItemsIndices, setViewableItemsIndices ] = useState([]);

    const handleVieweableItemsChanged = useCallback(({viewableItems, changed }) => {   
        setViewableItemsIndices(viewableItems.map(item=>item.index))
    }, []);

    // config that decides when an item is viewable
    const viewabilityConfig = useRef({
      // useRef to try to counter the view rerender thing
      itemVisiblePercentThreshold:80
    }).current;
    // wrapped handleViewChange in useCallback to try to handle the re-render error
    return (
      <SafeAreaView style={style.container}>
        <FlatListWrapper
          horizontal={true}
          //{/*give each data item an isViewable prop*/}
          data={DATA.map((item,i)=>{
            item.isViewable=viewableItemsIndices.find(ix=>ix == i)
            return item
          })}
          renderItem={item=><Item {...item}/>}
          keyExtractor={item => item.id}
          onViewableItemsChanged={({viewableItems, changed})=>{
            // set viewableItemIndices to the indices when view change
            setViewableItemsIndices(viewableItems.map(item=>item.index))
          }}
          //{/*config that decides when an item is viewable*/} 
          viewabilityConfig={{itemVisiblePercentThreshold:80}}
          extraData={viewableItemsIndices}
        />
       {/* Extra stuff that just tells you what items should be visible*/}
        <Text>Items that should be visible:</Text>
        {viewableItemsIndices.map(i=><Text key={'text-'+i}>  {DATA[i].title}</Text>)}
      </SafeAreaView>
    );
  }
  const style = StyleSheet.create({
    container:{
      padding:10,
      alignItems:'center'
    },

    item:{
      borderWidth:1,
      padding:5,
      borderColor:'green',
    },
    itemContainer:{
      flex:1,
      backgroundColor: 'transparent',
      marginVertical: 8,
      width:120,
      alignItems:'center',
      marginHorizontal: 3,

    }
  })

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      marginTop: StatusBar.currentHeight || 0,
    },
    item: {
      flex:1,
      backgroundColor: 'transparent',
      marginVertical: 8,
      width:120,
      alignItems:'center',
      marginHorizontal: 3,
    },
    title: {
      fontSize: 32,
    },
    tinyLogo: {
      borderRadius : 4,
      width: 150,
      height:150
    },
  });

  export default FlatListAnimation; 

```

FlatWrapper.js

```
//FlatListWrapper
import React, {useRef, useState, useCallback } from 'react';
import { 
    View, StyleSheet, FlatList , 
} from 'react-native';

const FlatListWrapper = (props) => {

  // useRef to avoid onViewableItemsChange on fly error
  const viewabilityConfig = useRef({
    // useRef to try to counter the view rerender thing
    itemVisiblePercentThreshold:80
  }).current;
  // wrapped handleViewChange in useCallback to try to handle the onViewableItemsChange on fly error
  const onViewChange = useCallback(props.onViewableItemsChanged,[])
  return (
      <View style={style.flatlistContainer}>
        <FlatList
          {...props}
          horizontal={true}
          onViewableItemsChanged={onViewChange}
        />
      </View>
  );
}
const style = StyleSheet.create({

  flatlistContainer:{
    borderWidth:1,
    borderColor:'red',
    width:'100%',
  },

})
export default FlatListWrapper

```