Воспроизведение анимации файла Lottie при выборе (Expo)

#javascript #react-native #animation #expo #lottie

#javascript #react-native #Анимация #expo #lottie

Вопрос:

Я хочу, чтобы он воспроизводился только при выборе карты, если карта не выбрана, она просто отображает файл lottie, но ничего не воспроизводится. Прямо сейчас я получаю сообщение об ошибке cannot read property 'play' of null . Когда я удаляю animationPress() и получаю файл для запуска, он также запускается с упомянутого initialSegment , что я передаю в него.

Что я здесь делаю не так?

Моя карточка, в которой находится файл Lottie:

    const animation = useRef(null);

    const animationPress = () => {
        animation.current.play();
    }

return(
{filteredData.map((item, index) => {
                            return (
                                <>
                                    <TouchableOpacity onPress={() => setSelected(item), animationPress()}>
                                        <View style={[{ alignItems: 'center' }, selected.id == item.id ? { paddingTop: 10 } : { paddingTop: 20 }]}>
                                            <CardioCard style={selected.id == item.id ? { backgroundColor: 'green', fontFamily: 'ssb_SemiBold' } : {}} >
                                                <CardItem style={[styles.card, selected.id == item.id ? { backgroundColor: 'green' } : {}]}>
                                                    <Text>

                                                        < LottieView
                                                            ref={animation}
                                                            source={require('../../assets/images/heartbeat.json')}
                                                            initialSegment={68,135}
                                                            autoPlay={true}
                                                            loop={true}
                                                            style={{ width: 100, height: 100 }} />
                                              
                                                    </Text>
                                                </CardItem>
                                            </CardioCard>
                                            <Text style={[{ fontSize: 18, color: 'hsl(98, 0%, 11%)', paddingLeft: 15 }, selected.id == item.id ? { fontFamily: 'ssb_SemiBold' } : {}]}>{item.name}</Text>
                                        </View>
                                    </TouchableOpacity>
                                </>
                            )
                        })}
...
)
 

Редактировать
Я также пытался сделать useState для кнопки autoplay and loop , чтобы они были ложными, но при нажатии кнопки она включалась true , но анимация не загружалась даже после нажатия кнопки.

     const [playAnimation, setPlayAnimation] = useState(false);

<TouchableOpacity onPress={() => setPlayAnimation(true)}>

    <LottieView
        source={require('../../assets/images/heartbeat.json')}
        autoPlay={playAnimation}
        loop={playAnimation}
        style={{ width: 100, height: 100 }}
    /> 
</TouchableOpacity>

 

это сводит меня с ума, и я не знаю, что делать дальше.

Комментарии:

1. вы можете попытаться предоставить параметр продолжительности для LottieView, когда элемент выбран, поскольку вы используете его для стилизации вашего компонента.

2. но длительность играет роль скорости. Вы говорите, скажите ему, что если он не выбран, его длительность равна нулю, а затем, если он выбран, имеет продолжительность, с которой выполняется анимация?

3. Попробуйте указать длительность с условием в реквизите длительности 1000 при выборе в противном случае 0

4. не так, здесь вы предоставили реквизит длительности в стиле props предоставьте реквизит длительности в компоненте LottieView, как показано ниже <Ссылка на LottieView={animation} источник={require(‘../../assets/images/heartbeat.json’)} initialSegment={68 135} Автозапуск={true} цикл={true} длительность ={selected.id == item.id ? 1000 : 0 } стиль={{ ширина: 100, высота: 100 }} />

5. Попробуйте обернуть компонент в отдельный компонент, а также попробуйте использовать внутреннее состояние для установки selected вместо этого в функции отображения элемента flatlist

Ответ №1:

Я новичок в react-native, но, думаю, это похоже на react. Не уверен, что правильно понял проблему.

В этом случае не следует ли использовать animation.current вместо animation в качестве ссылки на lottieView? или, по крайней мере, убедитесь, что ваша ссылка animation определена (не null), чтобы контейнер можно было смонтировать, даже если он не запущен, это также для вашей animationPress функции. Также вам следует отключить autoPlay I guess (поскольку вы хотите запустить анимацию с помощью кнопки).

 < LottieView
         ref={animation.current}
         source={require('../../assets/images/heartbeat.json')}
         initialSegment={68,135}
         autoPlay={false}
         loop={true}
         style={{ width: 100, height: 100 }} />
 

или

 {animation amp;amp; < LottieView
         ref={animation}
         source={require('../../assets/images/heartbeat.json')}
         initialSegment={68,135}
         autoPlay={false}
         loop={true}
         style={{ width: 100, height: 100 }} />}
 

И, конечно

    const animationPress = () => {
     if(animation?.current) {
        animation.current.play();
     }
    }

 

Комментарии:

1. спасибо, что нашли время, чтобы ввести это. К сожалению, он не отображал ни одной анимации. Я также новичок в react native, и уже кажется, что вы понимаете это лучше, чем я, хотя, лол

2. Попробуйте изменить ссылку, как я предложил, потому ref что это изменяемый объект, который содержит a current , который указывает на «реальный» контейнер. Поэтому я чувствую, что вам не следует так использовать ссылку.

3. Извините, но я немного смущен. Можно было бы объяснить это немного подробнее. Я пытался ref={animation.current} , но файл не загружался. Что я должен установить useRef , если нет null . Я тоже не понимаю, что на самом деле установить

4. Когда ваш компонент будет смонтирован, useRef изменится с null на изменяемый объект, содержащий current . Поэтому можно инициализировать его значением null, но вы должны убедиться, что ссылка была помещена перед ее использованием. Если нет, у вас будет ошибка. Я не знаю, какую библиотеку вы используете для react-native, но убедитесь, какое состояние ссылки требуется. Является ли это ссылкой на элемент в этом случае, вы должны поместить свою ссылку на элемент и передать ref.current свой компонент? или этот LottieView сам по себе является контейнером, и в этом случае ему просто нужно ref ?