簡體   English   中英

Animation in react native 在所有組件中啟動,而不是僅在按下的一個中啟動

[英]Animation in react native starts in all of the components instead the starting only in the pressed One

我是 React Native 的新手,也是 React Native 中的動畫新手。 我想要做的是填充它被按下的復選框,但是當我按下可觸摸不透明度時,我所做的所有復選框都填充了。 'color' 值由此const color = useRef(new Animated.Value(0)).current; 我不知道這是否是最好的方法。 我搜索了文檔並看到了類似的內容。

    const {
        clean,
        tasks,
        getTasksList,
        edited,
        toogleEdited,
        deleteList,
    } = useContext(listContext);
    const { taskEdited } = useContext(taskContext);
    const [listName, setListName] = useState("");
    const screenHeight = Math.round(Dimensions.get("window").height);
    const colors = useRef(
        Array.from({ length: tasks.length }).fill(new Animated.Value(0))
    );

    async function getListName() {
        setListName(await AsyncStorage.getItem("listName"));
    }
    async function asyncGetTasks() {
        await getTasksList();
    }
    useEffect(() => {
        getListName();
        asyncGetTasks();
    }, [edited, taskEdited]);
    return (
        <View style={styles.container}>
            <StatusBar hidden />
            <View style={styles.buttonsContainer}>
                <TouchableOpacity
                    onPress={() => {
                        clean();
                        navigation.goBack();
                    }}
                >
                    <MaterialIcons name="arrow-back" size={32} />
                </TouchableOpacity>
                <TouchableOpacity
                    onPress={() => {
                        deleteList();
                        clean();
                        navigation.goBack();
                    }}
                >
                    <MaterialIcons name="delete" size={32} color="#bc0000" />
                </TouchableOpacity>
            </View>
            <View style={styles.titleContent}>
                <Text style={styles.titleText}>{listName}</Text>
            </View>
            <ScrollView style={{ height: screenHeight }}>
                {tasks.length > 0 ? (
                    tasks.map((item, index) => (
                        <TouchableOpacity key={index} style={styles.task}>
                            <View style={{ flexDirection: "row" }}>
                                <TouchableOpacity
                                    style={{ alignSelf: "center", marginRight: 8 }}
                                    onPress={() => {
                                        console.log(colors.current[index]);

                                        Animated.timing(colors.current[index], {
                                            toValue: 1,
                                            duration: 1000,
                                        }).start();
                                        toogleEdited();
                                    }}
                                >
                                    <Animated.View
                                        style={{
                                            borderColor: "#000",
                                            borderWidth: 3,
                                            borderRadius: 100,
                                        }}
                                    >
                                        <Animated.View
                                            style={{
                                                backgroundColor: "#000",
                                                height: 22,
                                                width: 22,
                                                borderRadius: 100,
                                                opacity: colors.current[index],
                                            }}
                                            nativeID={item._id}
                                        ></Animated.View>
                                    </Animated.View>
                                </TouchableOpacity>
                                <View>
                                    <Text style={styles.taskText}>{item.title}</Text>
                                </View>
                            </View>

                            <Animated.View
                                style={{
                                    position: "absolute",
                                    alignItems: "center",
                                    alignContent: "center",
                                    opacity: 0.5,
                                    alignSelf: "center",
                                }}
                            >
                                <Text
                                    style={{
                                        color: "#000",
                                        opacity: 0,
                                        fontSize: 32,
                                    }}
                                >
                                    Done!!
                                </Text>
                            </Animated.View>
                        </TouchableOpacity>
                    ))
                ) : (
                    <View style={styles.emptyContent}>
                        <Text style={styles.emptyText}>This list don't have tasks yet</Text>
                    </View>
                )}
            </ScrollView>
            <TouchableOpacity
                style={{
                    position: "absolute",
                    top: screenHeight - 120,
                    right: 28,
                    flexDirection: "row",
                    width: 50,
                    alignSelf: "flex-end",
                }}
                onPress={() => navigation.navigate("NewTask")}
            >
                <Image source={PlusImage} />
            </TouchableOpacity>
        </View>
    );
}

如果您不明白,請隨時提問,我的代碼可能難以閱讀,但我正在努力!

編輯:我嘗試了一些建議,但仍然適用於所有人,並顯示了更多代碼以更全面

您將所有元素存儲為僅一個ref ,您應該使其更具動態性

const colors = useRef(Array.from({length: tasks.length} , _ => new Animated.Value(0))).current

使用.from({ length }, _ =>...)為數組中的每個插槽創建一個具有唯一 object 的數組(並且所有插槽都指向不同的 object)

現在您只能更改onPress中的一個元素

onPress={() => {
         console.log(colors[index]);
         Animated.timing(colors[index], {
         toValue: 1,
         duration: 1000,
         }).start();
    }}

另一個筆記,

不要在不需要onPress功能的地方使用TouchableOpacity ,它會阻止它的兒童可點擊性

為了在Animated.View中實現動畫行為,您應該將 animation 值與視圖style屬性鏈接起來

<Animated.View
    style={{ ...yourStyle... , 
             opacity: colors[index],
       }}
> 

將產生褪色 animation,而不opacity將為 0 / 1 符合 animation 值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM