React-Native 添加淡入动画

10
我会尽力完成翻译,以下是您需要的结果:

我正在尝试使用Hooks使每次加载组件时淡入该卡片,并在卸载后淡出,但我一直失败,急需他人帮助。请问你能否向我展示如何使用hooks每次加载和卸载时动画这个卡片。

这是我的组件:

import React, { useState } from "react";

const Home = (props) => {
  const renderCard = ({ item }) => {
    return (
      //I am trying to add a fadein to this everytime it loads and fadout when It unmounts
      <View>
        <Text style={styles.day}>{item}</Text>
        <MealCards
          item={state[item]}
          navigation={navigation}
          onChange={onChange}
        />
        <View style={styles.divider} />
      </View>
    );
  };
  return (
    <FlatList
      data={days}
      keyExtractor={(item) => item}
      showsHorizontalScrollIndicator={false}
      renderItem={renderCard}
    />
  );
};
4个回答

17
我认为最好的方法是使用Reanimated。
import Animated, { FadeIn, FadeOut } from    'react-native-reanimated';

<Animated.View
            key={'uniqueKey'}
            entering={FadeIn.duration(400)}
            exiting={FadeOut.duration(400)}
        />

额外提示: 如果您想重新触发动画,只需更改组件键属性即可 ;)


11

将你的组件包裹在一个 Animated.View 中,并通过 opacity 属性为其添加渐变动画。具体请参见:https://reactnative.dev/docs/animated

代码示例:

  const [fadeAnim] = useState(new Animated.Value(0));

  React.useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 1000,
    }).start();
  }, []);

  return (
    <Animated.View
      style={{
        opacity: fadeAnim,
      }}
    >
      {props.children}
    </Animated.View>
  );

上面的代码是用于淡入效果。淡出效果则在useEffect函数的返回函数中实现。

我该如何将这应用于我的平面列表,因为我仍然很迷茫,请你能帮助我吗? - Dilhan Bhagat
我会创建一个名为FadeInView或类似的组件。然后将此代码放入其中。然后您可以使用FadeInView作为父组件,例如<FadeInView><FlatListGoesHere /></FadeInView> - Benjamin Godlove
请问您能否向我展示如何使用淡入淡出来实现这个功能? - Dilhan Bhagat
1
我认为在 useEffect 的返回中尝试淡出实际上是行不通的。您的组件将在动画发生之前被卸载并消失。您需要保留该组件已挂载,并通过可见性属性/条件触发淡出动画。 - Jason Masters

5

@Benjamin Godlove的答案的基础上,这里提供了一个完全可行的淡入淡出示例。

我发现尝试使用useEffect返回语句来淡出无法正常工作(我认为组件在动画运行之前会卸载和取消渲染),所以我保持组件挂载并仅使用切换来影响不透明度/可见性。

type Props = {
  children: React.ReactNode;
  visible: boolean;
};

function FadePanel({children, visible}:Props){
  const fadeAnim = useRef(new Animated.Value(0)).current;
  React.useEffect(() => {
    if (visible) {
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 1000,
        useNativeDriver: true,
      }).start();
    } else if (!visible) {
      Animated.timing(fadeAnim, {
        toValue: 0,
        duration: 1000,
        useNativeDriver: true,
      }).start();
    }
  }, [visible]);
  return (
    <Animated.View
      style={{
        opacity:fadeAnim
      }}
    >
      {children}
    </Animated.View>
  )
}


1
应该是被接受的答案。在卸载时尝试动画会很麻烦。最好像你所做的那样使用感知动画。 - jakeforaker

1

你还可以使用一个名为react-native-fadeview-wrapper的库,它可以轻松覆盖所有淡入淡出动画,并且还可以自定义。

<FadeView visible={isVisible}>
    {/** any components of yours */}
</FadeView>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接