Анимация в react native запускается во всех компонентах, а не только в нажатой One. - PullRequest
1 голос
/ 17 июня 2020

Я новичок в React Native, а также в анимации в React Native. Что я пытаюсь сделать, так это заполнить флажок в нажатом состоянии, но так же, как я сделал все флажки заполненными, когда я нажимаю Touchable Opacity. значение '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>
    );
}

Если вы не понимаете, пожалуйста, не стесняйтесь спрашивать, мой код может быть трудно читать, но я работаю над этим!

edit: Я попробовал несколько советов, которые я получил здесь, но все еще подходит ко всем, и показал, что большая часть кода является более компромиссной

1 Ответ

2 голосов
/ 17 июня 2020

Вы храните все элементы только как один ref, вы должны сделать его более динамичным c вот так

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

используйте .from({ length }, _ => ...) для создания массива с уникальным объектом для каждого слота в массив (а не тот же объект, на который указывают все слоты)

Теперь вы можете изменить только один элемент в onPress

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

Другие примечания,

Не используйте TouchableOpacity там, где вам не нужна onPress функциональность, она блокирует кликабельность детей

Для достижения анимированного поведения в Animated.View, вы должны связать значение анимации с view style prop

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

создаст анимацию затухания, а opacity будет 0/1 соответствует значению анимации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...