| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- import { Image } from 'expo-image';
- import React, { useState } from 'react';
- import {
- Dimensions,
- FlatList,
- ImageBackground,
- StyleSheet,
- Text,
- TouchableOpacity,
- View,
- } from 'react-native';
- import { Images } from '@/constants/images';
- const { width } = Dimensions.get('window');
- interface Product {
- cover: string;
- name: string;
- level: string;
- quantity?: number;
- }
- interface ProductSwiperProps {
- products: Product[];
- onShowSwipe?: (index: number) => void;
- }
- export default function ProductSwiper({ products, onShowSwipe }: ProductSwiperProps) {
- const [current, setCurrent] = useState(0);
- const getProbability = (item: Product) => {
- return "10%"; // Placeholder
- };
- if (!products || products.length === 0) return null;
- const renderItem = ({ item, index }: { item: Product; index: number }) => (
- <TouchableOpacity
- activeOpacity={0.9}
- onPress={() => onShowSwipe?.(index)}
- style={styles.itemContainer}
- >
- <View style={styles.imageBox}>
- <Image source={{ uri: item.cover }} style={styles.image} contentFit="contain" />
- </View>
-
- {/* Details Button/Tag */}
- <ImageBackground
- source={{ uri: Images.box.detail.detailsBut }}
- style={styles.detailsTag}
- resizeMode="contain"
- >
- <View style={styles.detailsContent}>
- <Text style={styles.levelText}>
- {item.level === 'A' ? '超神款' :
- item.level === 'B' ? '欧皇款' :
- item.level === 'C' ? '隐藏款' : '普通款'}
- </Text>
- <Text style={styles.probText}>{getProbability(item)}</Text>
- </View>
- </ImageBackground>
- {/* Name Tag */}
- <ImageBackground
- source={{ uri: Images.box.detail.nameBg }}
- style={styles.nameTag}
- resizeMode="stretch"
- >
- <Text style={styles.nameText} numberOfLines={1}>{item.name}</Text>
- </ImageBackground>
- </TouchableOpacity>
- );
- return (
- <View style={styles.container}>
- <FlatList
- data={products}
- renderItem={renderItem}
- horizontal
- pagingEnabled
- showsHorizontalScrollIndicator={false}
- keyExtractor={(_, index) => index.toString()}
- onMomentumScrollEnd={(e) => {
- const contentOffset = e.nativeEvent.contentOffset;
- const viewSize = e.nativeEvent.layoutMeasurement;
- const pageNum = Math.floor(contentOffset.x / viewSize.width);
- setCurrent(pageNum);
- }}
- />
- {/* Left/Right Arrows if needed */}
- {current > 0 && (
- <View style={[styles.arrow, styles.leftArrow]}>
- <Image source={{ uri: Images.box.detail.left }} style={styles.arrowImg} contentFit="contain" />
- </View>
- )}
- {current < products.length - 1 && (
- <View style={[styles.arrow, styles.rightArrow]}>
- <Image source={{ uri: Images.box.detail.right }} style={styles.arrowImg} contentFit="contain" />
- </View>
- )}
- </View>
- );
- }
- const styles = StyleSheet.create({
- container: {
- width: '100%',
- height: 380, // Adjusted height
- alignItems: 'center',
- marginTop: 20,
- },
- itemContainer: {
- width: width, // Full width for paging
- height: '100%',
- justifyContent: 'center',
- alignItems: 'center',
- },
- imageBox: {
- width: '60%',
- height: '60%',
- justifyContent: 'center',
- alignItems: 'center',
- },
- image: {
- width: '100%',
- height: '100%',
- },
- detailsTag: {
- position: 'absolute',
- right: 40,
- bottom: 80,
- width: 100,
- height: 60,
- justifyContent: 'center',
- alignItems: 'center',
- },
- detailsContent: {
- alignItems: 'center',
- justifyContent: 'center',
- marginTop: 5,
- },
- levelText: {
- color: '#fff',
- fontSize: 12,
- fontWeight: 'bold',
- textShadowColor: '#000',
- textShadowOffset: { width: 1, height: 1 },
- textShadowRadius: 1,
- },
- probText: {
- color: '#fff',
- fontSize: 10,
- fontWeight: 'bold',
- textShadowColor: '#000',
- textShadowOffset: { width: 1, height: 1 },
- textShadowRadius: 1,
- },
- nameTag: {
- position: 'absolute',
- left: 40,
- top: 40,
- width: 40,
- height: 120,
- justifyContent: 'center',
- alignItems: 'center',
- paddingVertical: 10,
- },
- nameText: {
- color: '#000',
- fontSize: 12,
- fontWeight: 'bold',
- width: 12,
- textAlign: 'center',
- },
- arrow: {
- position: 'absolute',
- top: '50%',
- marginTop: -20,
- width: 40,
- height: 40,
- zIndex: 10,
- },
- leftArrow: {
- left: 10,
- },
- rightArrow: {
- right: 10,
- },
- arrowImg: {
- width: '100%',
- height: '100%',
- }
- });
|