import { BannerItem } from '@/services/base'; import { Image } from 'expo-image'; import React, { useEffect, useRef, useState } from 'react'; import { Dimensions, FlatList, StyleSheet, TouchableOpacity, View } from 'react-native'; const { width: SCREEN_WIDTH } = Dimensions.get('window'); // 小程序 banner 高度 432rpx,宽度100% const BANNER_HEIGHT = 216; // 432rpx / 2 interface BannerProps { data: BannerItem[]; onPress?: (item: BannerItem) => void; } export function Banner({ data, onPress }: BannerProps) { const [activeIndex, setActiveIndex] = useState(0); const flatListRef = useRef>(null); const autoPlayRef = useRef | null>(null); useEffect(() => { if (data.length <= 1) return; autoPlayRef.current = setInterval(() => { const nextIndex = (activeIndex + 1) % data.length; flatListRef.current?.scrollToIndex({ index: nextIndex, animated: true }); setActiveIndex(nextIndex); }, 5000); return () => { if (autoPlayRef.current) clearInterval(autoPlayRef.current); }; }, [activeIndex, data.length]); const renderItem = ({ item }: { item: BannerItem }) => ( onPress?.(item)}> ); const onScroll = (event: any) => { const offsetX = event.nativeEvent.contentOffset.x; const index = Math.round(offsetX / SCREEN_WIDTH); if (index !== activeIndex && index >= 0 && index < data.length) { setActiveIndex(index); } }; return ( item.id || String(index)} horizontal pagingEnabled showsHorizontalScrollIndicator={false} onScroll={onScroll} scrollEventThrottle={16} getItemLayout={(_, index) => ({ length: SCREEN_WIDTH, offset: SCREEN_WIDTH * index, index, })} /> {data.map((_, index) => ( ))} ); } const styles = StyleSheet.create({ container: { width: '100%', height: BANNER_HEIGHT, marginTop: 11, overflow: 'hidden', }, bannerImage: { width: SCREEN_WIDTH, height: BANNER_HEIGHT, }, dots: { position: 'absolute', bottom: 10, left: 0, right: 0, flexDirection: 'row', justifyContent: 'center', }, dot: { width: 6, height: 6, borderRadius: 3, backgroundColor: 'rgba(255,255,255,0.5)', marginHorizontal: 3, }, dotActive: { backgroundColor: '#fff', }, });