我是react native的新手,我在react-native中找到了Animated,所以有一个带有图像的旋转木马。我可以只水平滑动它,但我希望它也可以默认自动滚动。当它变成最后一个滑块时,它应该从带有动画的第一个滑块开始。请帮我解决这个问题,谢谢!
Carousel.js (这里是共享代码- https://codeshare.io/G8EZOZ):
import React, { useCallback, useEffect, useRef, useState } from 'react'
import {
SafeAreaView,
ScrollView,
StyleSheet,
View,
ImageBackground,
Animated,
useWindowDimensions,
Alert,
Pressable,
} from 'react-native'
import { useDispatch, useSelector } from 'react-redux'
import { useTranslation } from 'react-i18next'
import i18next from 'i18next'
import * as slidersAction from '../../store/actions/sliders'
import Loading from './Loading'
const Carousel = (props) => {
const scrollX = useRef(new Animated.Value(0)).current
const lang = i18next.language
const { width: windowWidth } = useWindowDimensions()
const { t, i18n } = useTranslation()
const [error, setError] = useState()
const [isLoading, setisLoading] = useState(false)
const dispatch = useDispatch()
const images = useSelector((state) => state.sliders.availableSliders)
const loadSliders = useCallback(async () => {
setisLoading(true)
setError(null)
try {
await dispatch(slidersAction.fetchSliders(t('sliders.errorMessageFetch')))
} catch (err) {
setError(err)
}
setisLoading(false)
})
useEffect(() => {
loadSliders()
}, [])
if (error) {
Alert.alert(t('sliders.errorTitle'), t('sliders.errorMessageFetch'), [{ text: 'Ок' }])
setError(null)
}
if (isLoading) {
return <Loading />
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.scrollContainer}>
<ScrollView
horizontal={true}
style={styles.scrollViewStyle}
pagingEnabled
showsHorizontalScrollIndicator={false}
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: {
x: scrollX,
},
},
},
],
{ useNativeDriver: false }
)}
scrollEventThrottle={1}
>
{images.map((image, imageIndex) => {
return (
<Pressable
key={imageIndex}
onPress={() =>
+image.enableLink
? props.navigation.navigate('Home', {
categoryId: image.categoryId,
categoryTitle: image.title,
categoryTitleKg: image.titleKg,
lang: lang,
})
: {}
}
>
<View style={{ width: windowWidth, height: 100, maxHeight: 160 }}>
<ImageBackground
source={{ uri: image.imageUrl }}
style={styles.card}
resizeMode='contain'
/>
</View>
</Pressable>
)
})}
</ScrollView>
<View style={styles.indicatorContainer}>
{images.map((image, imageIndex) => {
const width = scrollX.interpolate({
inputRange: [
windowWidth * (imageIndex - 1),
windowWidth * imageIndex,
windowWidth * (imageIndex + 1),
],
outputRange: [8, 16, 8],
extrapolate: 'clamp',
})
return <Animated.View key={imageIndex} style={[styles.normalDot, { width }]} />
})}
</View>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
scrollContainer: {
alignItems: 'center',
justifyContent: 'center',
},
card: {
flex: 1,
overflow: 'hidden',
alignItems: 'center',
justifyContent: 'center',
},
normalDot: {
height: 8,
width: 8,
borderRadius: 4,
backgroundColor: 'silver',
marginHorizontal: 4,
},
indicatorContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
marginBottom: 1,
},
})
export default Carousel
发布于 2021-02-17 22:20:38
虽然您提供的代码不足以创建一个可工作的示例来测试这一点,但您应该能够使用ScrollView's scrollTo component method实现这一点。
要自动滚动,可以在loadSliders函数中调用setTimeout:
const loadSliders = useCallback(async () => {
setisLoading(true)
setError(null)
try {
await dispatch(slidersAction.fetchSliders(t('sliders.errorMessageFetch')))
} catch (err) {
setError(err)
}
setisLoading(false)
// new code
let stopAutoScroll = null // consider making this a state variable
const autoScrollOneStep = () => {
YOUR_SCROLLVIEW_REF_HERE.scrollTo({ x: YOUR_CURRENT_PAGE_X + X_OFFSET, animated: true })
stopAutoScroll = setTimeout(autoScrollOneStep, 2000)
}
stopAutoScroll = setTimeout(autoScrollOneStep, 2000)
})
您可以随时使用clearTimeout(stopAutoScroll)
停止自动滚动(可能是在onScroll方法中,这样一旦用户滚动,自动滚动就会停止
https://stackoverflow.com/questions/66100764
复制相似问题