You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Expo环境下获取手机全部照片并在FlatList中展示

Expo环境下获取手机照片并在FlatList中展示的解决方案

推荐使用expo-media-library——这是Expo官方维护的媒体资源操作库,完全适配Expo环境,能稳定实现获取手机照片、视频等媒体资源的需求,替代无法正常工作的react-native-cameraroll。

实现步骤:

  1. 安装依赖
    在项目根目录执行命令:

    npx expo install expo-media-library
    
  2. 配置权限
    在app.json或app.config.js中添加媒体库访问权限配置,确保App能请求用户授权:

    {
      "expo": {
        "ios": {
          "infoPlist": {
            "NSPhotoLibraryUsageDescription": "需要访问您的照片库来展示图片"
          }
        },
        "android": {
          "permissions": [
            "android.permission.READ_MEDIA_IMAGES",
            "android.permission.WRITE_EXTERNAL_STORAGE"
          ]
        }
      }
    }
    
  3. 获取照片并在FlatList展示
    以下是完整的组件示例,包含权限请求、照片获取和FlatList渲染:

    import React, { useState, useEffect } from 'react';
    import { View, FlatList, Image, StyleSheet, Alert, Text } from 'react-native';
    import * as MediaLibrary from 'expo-media-library';
    
    const PhotoGallery = () => {
      const [photos, setPhotos] = useState([]);
      const [hasPermission, setHasPermission] = useState(null);
    
      useEffect(() => {
        const init = async () => {
          const { status } = await MediaLibrary.requestPermissionsAsync();
          setHasPermission(status === 'granted');
          
          if (status === 'granted') {
            // 获取所有图片资源,按创建时间倒序排列
            const media = await MediaLibrary.getAssetsAsync({
              mediaType: MediaLibrary.MediaType.photo,
              sortBy: [MediaLibrary.SortBy.creationTime],
              first: 50, // 首次加载50张,可按需调整
            });
            setPhotos(media.assets);
          } else {
            Alert.alert('权限不足', '需要授予照片库访问权限才能展示图片');
          }
        };
    
        init();
      }, []);
    
      if (hasPermission === null) {
        return <View />;
      }
      if (hasPermission === false) {
        return <View style={styles.container}><Text>无法访问照片库</Text></View>;
      }
    
      return (
        <View style={styles.container}>
          <FlatList
            data={photos}
            numColumns={3}
            keyExtractor={(item) => item.id}
            renderItem={({ item }) => (
              <Image
                style={styles.photo}
                source={{ uri: item.uri }}
                resizeMode="cover"
              />
            )}
          />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
        justifyContent: 'center',
        alignItems: 'center',
      },
      photo: {
        width: '33.33%',
        height: 120,
        borderWidth: 1,
        borderColor: '#eee',
      },
    });
    
    export default PhotoGallery;
    

额外优化建议:

  • 分页加载:如果照片数量较多,避免一次性全部加载,可利用MediaLibrary.getAssetsAsync的after参数实现滚动分页,提升性能。
  • 缓存处理:可以结合expo-image库替代原生Image组件,实现图片缓存和更优的加载体验。

内容的提问来源于stack exchange,提问作者Huy Ngô

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:05:25