作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 React Native 中使用钩子(Hook)和 javascript 制作无限图像轮播。
我几乎完成了代码,轮播也工作得非常好,但轮播下方的事件点比图像运行得更快。我已经尝试了几件事,但遗憾的是没有成功。
提前致谢。
import React, {
useEffect,
useState,
useRef,
useCallback,
createRef,
} from 'react';
import {
StyleSheet,
View,
Dimensions,
FlatList,
LayoutAnimation,
UIManager,
Text,
} from 'react-native';
import {ActivityIndicator} from 'react-native';
import {Image} from 'react-native-elements';
const HomeCarousel = ({data}) => {
const [dimension, setDimension] = useState(Dimensions.get('window'));
const [index, setIndex] = useState(0);
const [dataState, setDataState] = useState(data);
slider = createRef();
let intervalId = null;
const onChange = () => {
setDimension(Dimensions.get('window'));
};
useEffect(() => {
Dimensions.addEventListener('change', onChange);
return () => {
Dimensions.removeEventListener('change', onChange);
};
});
useEffect(() => {
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}, []);
viewabilityConfig = {
viewAreaCoveragePercentThreshold: 50,
};
const onViewableItemsChanged = ({viewableItems, changed}) => {
if (viewableItems.length > 0) {
let currentIndex = viewableItems[0].index;
if (currentIndex % data.length === data.length - 1) {
setIndex(currentIndex),
setDataState(dataState => [...dataState, ...data]);
} else {
console.log(currentIndex, 'else');
setIndex(currentIndex);
}
}
};
const onSlideChange = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeIn);
const newIndex = index + 1;
setIndex(newIndex);
slider?.current?.scrollToIndex({
index: index,
animated: true,
});
};
const startInterval = useCallback(() => {
intervalId = setInterval(onSlideChange, 3000);
}, [onSlideChange]);
useEffect(() => {
startInterval();
return () => {
clearInterval(intervalId);
};
}, [onSlideChange]);
const viewabilityConfigCallbackPairs = useRef([
{viewabilityConfig, onViewableItemsChanged},
]);
const renderIndicator = ()=>{
const indicators = [];
data.map((val,key)=>(
indicators.push(
<Text
key={key}
style={
key === index % data.length ? {color: 'lightblue',fontSize:10,marginBottom: 8,marginHorizontal:1} :
{color: '#888',fontSize:10,marginBottom: 8,marginHorizontal:1}
}>
⬤
</Text>
)
));
return indicators;
}
return (
<View style={{width: dimension.width,height: 280, backgroundColor: '#fff'}}>
<FlatList
ref={slider}
horizontal
pagingEnabled
snapToInterval={dimension?.width}
decelerationRate="fast"
bounces={false}
showsHorizontalScrollIndicator={false}
data={dataState}
renderItem={({item, index}) => (
<>
<View>
<Image
source={{uri: `${item.url}`}}
style={{
width: dimension?.width,
height: 250,
resizeMode: 'cover',
}}
PlaceholderContent={<ActivityIndicator />}
/>
</View>
</>
)}
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
getItemLayout={(data, index) => ({
length: dimension?.width,
offset: dimension?.width * index,
index,
})}
windowSize={1}
initialNumToRender={1}
maxToRenderPerBatch={1}
removeClippedSubviews={true}
/>
<View
style={{
flexDirection: 'row',
position: 'absolute',
bottom: 0,
alignSelf: 'center',
}}>
{renderIndicator()}
</View>
</View>
);
};
const styles = StyleSheet.create({});
export default HomeCarousel;
作为 props 传递给这个组件的数据是
export const carouselImages = [
{url: 'https://i.ibb.co/FDwNR9d/img1.jpg'},
{url: 'https://i.ibb.co/7G5qqGY/1.jpg'},
{url: 'https://i.ibb.co/Jx7xqf4/pexels-august-de-richelieu-4427816.jpg'},
{url: 'https://i.ibb.co/GV08J9f/pexels-pixabay-267202.jpg'},
{url: 'https://i.ibb.co/sK92ZhC/pexels-karolina-grabowska-4210860.jpg'},
];
最佳答案
哦哦,我自己修好了这是完美的工作代码完整代码。 😄
import React, {
useEffect,
useState,
useRef,
useCallback,
createRef,
} from 'react';
import {
StyleSheet,
View,
Dimensions,
FlatList,
LayoutAnimation,
UIManager,
Text,
} from 'react-native';
import {ActivityIndicator} from 'react-native';
import {Image} from 'react-native-elements';
const HomeCarousel = ({data}) => {
const [dimension, setDimension] = useState(Dimensions.get('window'));
const [index, setIndex] = useState(0);
const [dataState, setDataState] = useState(data);
const [indicatorIndex, setindicatorIndex] = useState();
slider = createRef();
let intervalId = null;
const onChange = () => {
setDimension(Dimensions.get('window'));
};
useEffect(() => {
Dimensions.addEventListener('change', onChange);
return () => {
Dimensions.removeEventListener('change', onChange);
};
});
useEffect(() => {
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}, []);
viewabilityConfig = {
viewAreaCoveragePercentThreshold: 50,
};
const onViewableItemsChanged = ({viewableItems, changed}) => {
if (viewableItems.length > 0) {
let currentIndex = viewableItems[0].index;
if (currentIndex % data.length === data.length - 1) {
setIndex(currentIndex), setindicatorIndex(currentIndex);
setDataState(dataState => [...dataState, ...data]);
} else {
console.log(currentIndex, 'else');
setIndex(currentIndex);
setindicatorIndex(currentIndex);
}
}
};
const onSlideChange = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeIn);
const newIndex = index + 1;
setIndex(newIndex);
slider?.current?.scrollToIndex({
index: index,
animated: true,
});
};
const startInterval = useCallback(() => {
intervalId = setInterval(onSlideChange, 3000);
}, [onSlideChange]);
useEffect(() => {
startInterval();
return () => {
clearInterval(intervalId);
};
}, [onSlideChange]);
const viewabilityConfigCallbackPairs = useRef([
{viewabilityConfig, onViewableItemsChanged},
]);
const renderIndicator = () => {
const indicators = [];
data.map((val, key) =>
indicators.push(
<Text
key={key}
style={
key === indicatorIndex % data.length
? {
color: 'lightblue',
fontSize: 10,
marginBottom: 8,
marginHorizontal: 1,
}
: {
color: '#888',
fontSize: 10,
marginBottom: 8,
marginHorizontal: 1,
}
}>
⬤
</Text>,
),
);
return indicators;
};
return (
<View
style={{width: dimension.width, height: 280, backgroundColor: '#fff'}}>
<FlatList
ref={slider}
horizontal
pagingEnabled
snapToInterval={dimension?.width}
decelerationRate="fast"
bounces={false}
showsHorizontalScrollIndicator={false}
data={dataState}
renderItem={({item, index}) => (
<>
<View>
<Image
source={{uri: `${item.url}`}}
style={{
width: dimension?.width,
height: 250,
resizeMode: 'cover',
}}
PlaceholderContent={<ActivityIndicator />}
/>
</View>
</>
)}
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
getItemLayout={(data, index) => ({
length: dimension?.width,
offset: dimension?.width * index,
index,
})}
windowSize={1}
initialNumToRender={1}
maxToRenderPerBatch={1}
removeClippedSubviews={true}
/>
<View
style={{
flexDirection: 'row',
position: 'absolute',
bottom: 0,
alignSelf: 'center',
}}>
{renderIndicator()}
</View>
</View>
);
};
const styles = StyleSheet.create({});
export default HomeCarousel;
关于javascript - 如何在 React Native 中制作带有钩子(Hook)的无限图像轮播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67337104/
我是一名优秀的程序员,十分优秀!