react native 实现相册
实现相册功能的核心模块
React Native 实现相册功能主要依赖以下核心模块:
- 媒体库访问:使用
expo-media-library或react-native-fs获取设备图片 - 图片展示:通过
FlatList或SectionList实现网格布局 - 权限管理:处理 iOS/Android 的存储权限请求
安装必要依赖
# 使用 Expo 生态
expo install expo-media-library expo-image-picker
# 非 Expo 项目
npm install react-native-permissions @react-native-camera-roll/camera-roll
权限请求实现
iOS 需要在 Info.plist 添加:
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择照片</string>
Android 需要在 AndroidManifest.xml 添加:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
权限请求代码示例:
import { PermissionsAndroid, Platform } from 'react-native';
import * as MediaLibrary from 'expo-media-library';
const requestPermission = async () => {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
const { status } = await MediaLibrary.requestPermissionsAsync();
return status === 'granted';
};
获取相册图片数据
使用 expo-media-library 获取媒体资源:
const loadPhotos = async () => {
const { granted } = await MediaLibrary.getPermissionsAsync();
if (!granted) return;
const albums = await MediaLibrary.getAlbumsAsync();
const cameraRoll = albums.find(album => album.title === 'Camera Roll');
const { assets } = await MediaLibrary.getAssetsAsync({
album: cameraRoll,
mediaType: ['photo'],
first: 100,
sortBy: ['creationTime'],
});
return assets;
};
图片网格布局实现
使用 FlatList 展示图片:
import { FlatList, Image, StyleSheet } from 'react-native';
const renderItem = ({ item }) => (
<Image
source={{ uri: item.uri }}
style={styles.thumbnail}
/>
);
const PhotoGrid = ({ photos }) => (
<FlatList
data={photos}
renderItem={renderItem}
keyExtractor={item => item.id}
numColumns={3}
contentContainerStyle={styles.grid}
/>
);
const styles = StyleSheet.create({
thumbnail: {
width: 120,
height: 120,
margin: 2
},
grid: {
padding: 5
}
});
图片选择功能扩展
集成图片选择器实现单选/多选:
import * as ImagePicker from 'expo-image-picker';
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsMultipleSelection: true,
selectionLimit: 5
});
if (!result.canceled) {
return result.assets;
}
};
性能优化建议
对于大型相册加载:
- 实现分页加载 (
getAssetsAsync的after参数) - 使用
resizeMode="cover"优化图片渲染 - 考虑使用
react-native-fast-image替代默认Image组件 - 对 Android 大图集添加
decodeWidth: 200参数降低内存占用
平台差异处理
iOS 特殊处理:
if (Platform.OS === 'ios') {
// iOS 需要额外处理相册变更监听
const subscription = MediaLibrary.addListener(() => {
// 相册内容变化时重新加载
});
}
Android 10+ 适配:
if (Platform.Version >= 29) {
// 使用 MediaStore API 替代直接文件访问
const uri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
id
);
}






