Mi proyecto bastante básico de reacción nativa usa expo-media-library para recuperar algunas fotografías del álbum de fotos de un usuario, presentándolas en una pila de tarjetas, algo similar a Tinder. Mi código generalmente funciona, sin embargo, en lugar de mostrar solo la foto/tarjeta superior, se muestran varios otros en los primeros segundos y no puedo entender por qué. Creo que tiene que ver con el tamaño de las imágenes y la demora en cargarlas pero no estoy seguro. Realmente agradecería consejos sobre cómo solucionar esto.
Esto es lo que está pasando:
Como puede ver, en lugar de mostrar la primera imagen en la pila, primero se muestra otra imagen brevemente aunque no he codificado para que esto suceda.
Aquí está mi código (omitiendo importaciones y estilos):
const ImageStack = ({navigation, route}) => { const [status, requestPermission] = MediaLibrary.usePermissions() const [photos, setPhotos] = useState([]) //where we store stack of cards const [isLoading, setIsLoading]=useState(true) //only displaying stack when images have loaded // On load, retrieve photos from gallery useEffect(async()=>{ const getPhotos = await getAllPhotos(route.params.id)//id for the album is passed to component setPhotos(getPhotos) setIsLoading(false) // only when photos have been retrieved should they be displayed },[]) // function to retrieve photos from gallery const getAllPhotos = async (id) => { let album = await MediaLibrary.getAssetsAsync({album: id, mediaType: 'photo', first: 20, sortBy: ['creationTime']}) const foundPhotos = album['assets'] const updatedPhotos = [] for (let i=0;i<foundPhotos.length;i++){ const updatedPhoto = await MediaLibrary.getAssetInfoAsync(foundPhotos[i].id) updatedPhotos.push({ uri: updatedPhoto['localUri'], id: updatedPhoto['id'] }) } return updatedPhotos } const renderCards = () => { return photos.map((item, i)=>{ return( <Animated.View key={item.id} style={{height: SCREEN_HEIGHT -120, width: SCREEN_WIDTH, padding: 10, position: 'absolute'}}> <Image source={{uri: item.uri}} style={{flex: 1, height: null, width: null, resizeMode: 'cover', borderRadius: 20}}/> </Animated.View> ) }) } return ( <View style={{flex:1}}> <View style={{height:60}}> </View> <View style={{flex:1}}> {!isLoading && renderCards()} //Only render the photo cards when loaded </View> <View style={{height:60}}> </View> </View>¿Alguna sugerencia de cómo solucionar esto? ¡Gracias!
Arreglado esto. Así que el problema era el tamaño de las imágenes. Agregué compresión de imagen que solucionó completamente el problema:
const compressedImage = await ImageManipulator.manipulateAsync(updatedPhoto.localUri, [], { compress: 0.2 });