import { ThemedText } from '@/components/themed-text'; import { Image } from 'expo-image'; import React, { useEffect, useRef, useState, useCallback } from 'react'; import { ActivityIndicator, Dimensions, Modal, PanResponder, Platform, StatusBar, StyleSheet, TouchableOpacity, View, BackHandler, } from 'react-native'; const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); export interface FullscreenImageModalProps { visible: boolean; onClose: () => void; imageUrl: string; onPrevious?: () => void; onNext?: () => void; hasNext?: boolean; hasPrevious?: boolean; } export function FullscreenImageModal({ visible, onClose, imageUrl, onPrevious, onNext, hasNext = false, hasPrevious = false, }: FullscreenImageModalProps) { const [isLoading, setIsLoading] = useState(true); const handleClose = useCallback(() => { onClose(); }, [onClose]); // 重置状态当模态框打开/关闭时 useEffect(() => { if (visible) { setIsLoading(true); } }, [visible]); // 处理图片加载完成 const handleImageLoad = () => { setIsLoading(false); }; // 处理图片加载错误 const handleImageError = (error: any) => { console.error('图片加载错误:', error); setIsLoading(false); }; // 图片点击处理(直接关闭) const handleImagePress = () => { handleClose(); }; // 创建手势处理器 const panResponder = useRef( PanResponder.create({ onMoveShouldSetPanResponder: (_, gestureState) => { // 只有水平移动时才响应 return Math.abs(gestureState.dx) > Math.abs(gestureState.dy) && Math.abs(gestureState.dx) > 10; }, onPanResponderRelease: (_, gestureState) => { const threshold = screenWidth / 4; // 滑动屏幕宽度的1/4触发切换 if (gestureState.dx > threshold && hasPrevious) { // 向右滑动,显示上一个 onPrevious?.(); } else if (gestureState.dx < -threshold && hasNext) { // 向左滑动,显示下一个 onNext?.(); } }, }) ).current; // 处理返回键(Android) useEffect(() => { const handleBackPress = () => { if (visible) { handleClose(); return true; } return false; }; const subscription = BackHandler.addEventListener('hardwareBackPress', handleBackPress); return () => subscription.remove(); }, [visible, handleClose]); if (!visible) return null; return ( {/* 状态栏处理 */} {Platform.OS === 'android' && ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#000', }, imageContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, imageWrapper: { flex: 1, width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, image: { width: screenWidth, height: screenHeight, backgroundColor: '#000', }, loadingOverlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0, 0, 0, 0.3)', }, leftIndicator: { position: 'absolute', left: 20, top: '50%', marginTop: -20, width: 40, height: 40, borderRadius: 20, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center', zIndex: 10, }, rightIndicator: { position: 'absolute', right: 20, top: '50%', marginTop: -20, width: 40, height: 40, borderRadius: 20, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center', zIndex: 10, }, indicatorIcon: { fontSize: 24, color: '#fff', fontWeight: 'bold', }, }); export default FullscreenImageModal;