이미지 피커 만들기
React Native CameraRoll React Native ImagePicker
이 두 라이브러리를 많이 사용하는데 Expo에선 사용할 수 없음
Expo 자체 ImagePicker 가 있기에 그걸 쓰면 될 듯 MediaLibrary 도 있음.
npx expo install expo-media-library
npx expo install expo-image-picker
권한 요청의 경우
- 맨처음 들어왔을 때
- 권한이 필요할 때
케바케임
접근했을 때 권한 요청할 것임.
const [status, requestPermission] = MediaLibrary.usePermissions();
status 보면 granted 에서 확인할 수 있음.
그리고, 접근권한은 나중에 봐야겠지만 결국 app.json 파일 안에서 설정해주면 된다. 아래와 같이 일단은 설정함.
"ios": {
"supportsTablet": true,
"infoPlist": {
"NSPhotoLibraryUsageDescription": "The app access the photo library to upload a profile photo and use it on the post"
}
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#f97316"
},
"permission": ["READ_EXTERNAL_STORAGE"]
},
이미지 가져오기
getAssetAsync
- after :
- first : 한번에 몇장씩
- sortBy : 정렬
id, filename, uri 가 필요함.
아이 몰라 코드 복사함
import {
Alert,
StyleSheet,
Text,
View,
FlatList,
Pressable,
useWindowDimensions,
Image,
} from 'react-native';
import PropTypes from 'prop-types';
import { useNavigation } from '@react-navigation/native';
import { useCallback, useEffect, useLayoutEffect, useState } from 'react';
import HeaderRight from '../components/HeaderRight';
import * as MediaLibrary from 'expo-media-library';
const ImagePickerScreen = () => {
const navigation = useNavigation();
const [status, requestPermission] = MediaLibrary.usePermissions();
useEffect(() => {
(async () => {
const { granted } = await requestPermission();
if (!granted) {
Alert.alert('사진접근 권한', '접근권한이 필요합니다.', [
{
text: '확인',
onPress: () =>
navigation.canGoBack() && navigation.goBack(),
},
]);
}
})();
}, [navigation, requestPermission]);
const width = useWindowDimensions().width / 3;
const [photos, setPhotos] = useState([]);
const [listInfo, setListInfo] = useState({
endCursor: '',
hasNextPage: true,
});
const getPhotos = useCallback(async () => {
const options = {
first: 30,
sortBy: [MediaLibrary.SortBy.creationTime],
};
if (listInfo.hasNextPage) {
const { assets, endCursor, hasNextPage, totalCount } =
await MediaLibrary.getAssetsAsync(options);
setPhotos(assets);
setListInfo({ endCursor, hasNextPage });
}
}, [listInfo.hasNextPage]);
useEffect(() => {
if (status?.granted) {
getPhotos();
}
}, [status?.granted, getPhotos]);
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => <HeaderRight onPress={() => {}} />,
});
});
return (
<View style={styles.container}>
<FlatList
key={'#'}
style={styles.list}
data={photos}
renderItem={({ item }) => (
<Pressable style={{ width, height: width }}>
<Image
source={{ uri: item.uri }}
style={styles.photo}
/>
</Pressable>
)}
numColumns={3}
/>
</View>
);
};
ImagePickerScreen.propTypes = {};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 30,
},
list: {
width: '100%',
},
photo: {
width: '100%',
height: '100%',
},
});
export default ImagePickerScreen;
새로고침하기
당겨서 새로고침 하는 경우 onRefresh
- 새로고침 함수
- 당겨서 새로고침 기능
refreshing
- 새로고침할 때, 새 데이터를 가져오는 동안 true로 설정