skip to Main Content

here is my code.

  const actionButtonsAnimated = new Animated.Value(0);
  const animated = new Animated.Value(255);

  const animateTrendingCardSheet = () => {
   Animated.timing(animated, {
     toValue: 0,
     duration: 1500,
     useNativeDriver: true,
    }).start();
    Animated.timing(actionButtonsAnimated, {
      toValue: -180,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  }; 


<Animated.View
        style={[
          {
            transform: [{ translateY: actionButtonsAnimated }],
          },
        ]}
      >
        <MainActionButtons />
      </Animated.View>

      <Animated.View
        style={[
          {
            transform: [{ translateY: animated }],
            width: "100%",
            position: "absolute",
            bottom: 0,
          },
        ]}
      >
        <View style={styles.trendingCards}>
          <Text h5 center color={colors.trendingText}>
            Trending in your area...
          </Text>

          <View style={styles.flatlistWrapper}>
            <FlatList
              horizontal={true}
              data={trendingCards}
              renderItem={({ item }) => <TrendingCardComponent card={item} />}
            />
          </View>
        </View>
      </Animated.View>

so if i call the animateTrendingCardSheet function inside useEffect like this.

useEffect(() => {
animateTrendingCardSheet()
}, [])

it works as expected but once i put it in a condition that it should be called after the API call has been finished it does not work at all if i again save the file it hot reload animation works


  useEffect(() => {
    if (loadTrendingCard) {
      animateTrendingCardSheet();
    }
  }, [loadTrendingCard]);

2

Answers


  1. Chosen as BEST ANSWER

    The above answer is good but it does not solve my problem, its all due to a stupid mistake, the issue was i was setting the state before calling the animation call function, as the state changes and it interfere the animation i had to use useRef like this.

    const actionButtonsAnimated = useRef(new Animated.Value(initialActionButton)).current;
    
    const animated = useRef(new Animated.Value(initialAnimated)).current;
    

    it reference the state and animation works as expected.


  2. Your issue is that after the first call to animateTrendingCardSheet the toValue that you are animating to is the current value of your Animated variables; so it looks like nothing is happening. You can counteract this by resetting your animation variables before calling your animation function:

    import * as React from 'react';
    import {
      Text,
      View,
      StyleSheet,
      Animated,
      TouchableOpacity,
      FlatList,
      Button
    } from 'react-native';
    import Constants from 'expo-constants';
    
    const MainActionButtons = () => {
      return (
        <View
          style={{
            flexDirection: 'row',
            width: '100%',
            justifyContent: 'space-between',
          }}>
          <TouchableOpacity>Btn 1</TouchableOpacity>
          <TouchableOpacity>Btn 2</TouchableOpacity>
          <TouchableOpacity>Btn 3</TouchableOpacity>
          <TouchableOpacity>Btn 4</TouchableOpacity>
        </View>
      );
    };
    
    const TrendingCardComponent = ({ card }) => {
      return (
        <View style={{ width: '100%' }}>
          <Text>{card.title}</Text>
          <Text>{card.message}</Text>
        </View>
      );
    };
    
    const trendingCards = [
      { title: 'A Cool Card', message: 'A cool message' },
      { title: 'Card 1', message: 'A cool message' },
      { title: 'A Cool Card', message: 'A cool message' },
      { title: 'A Cool Card', message: 'A cool message' },
    ];
    
    const initialActionButton = 0;
    const initialAnimated = 255;
    export default function App() {
      const actionButtonsAnimated = new Animated.Value(initialActionButton);
      const animated = new Animated.Value(initialAnimated);
      const opacity = new Animated.Value(1)
    
      const onApiCall = ()=>{
        // set opacity to 0
        Animated.timing(opacity,{toValue:0,duration:500}).start(()=>{
          // when view is invisible do resets
          animated.setValue(initialAnimated)
          actionButtonsAnimated.setValue(initialActionButton)
          Animated.timing(opacity,{toValue:1,duration:500}).start()
          animateTrendingCardSheet()
        })
      }
    
      const animateTrendingCardSheet = () => {
        Animated.timing(animated, {
          toValue: 0,
          duration: 1500,
          useNativeDriver: true,
        }).start();
        Animated.timing(actionButtonsAnimated, {
          toValue:  -180 ,
          duration: 1000,
          useNativeDriver: true,
        }).start();
      };
      // React.useEffect(() => {
      //   animateTrendingCardSheet();
      // }, []);
      return (
        <View style={styles.container}>
          <Button title="Simulate API call" onPress={onApiCall}/>
            
          <Animated.View
            style={[
              {
                transform: [{ translateY: actionButtonsAnimated }],
                opacity
              },
            ]}>
            <MainActionButtons />
          </Animated.View>
    
          <Animated.View
            style={[
              {
                transform: [{ translateY: animated }],
                width: '100%',
                position: 'absolute',
                bottom: 0,
                opacity
              },
            ]}>
            <View style={styles.trendingCards}>
              <Text>Trending in your area...</Text>
              <View style={styles.flatlistWrapper}>
                <FlatList
                  style={{ flex: 1 }}
                  horizontal={true}
                  data={trendingCards}
                  renderItem={({ item }) => <TrendingCardComponent card={item} />}
                />
              </View>
            </View>
          </Animated.View>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
      flatlistWrapper: {
        width: '100%',
        height: 200,
      },
    });
    

    Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search