[React-Native] 끄적이기
by 담배맛구마모듈단위로 정리해보자
Print Image on network
이미지는 출력을 Image
컴포넌트로 출력하면 되고 네트워크 상에 있는 이미지를 가져올 때에는 width와 height를 명확하게 제시를 해줘야 한다. 지정안하면 에러는 안뜨는데 그냥 안 보인다. 그래서 나는 이미지 크기와 디스플레이 크기의 비율인 ratio를 계산해서 사용했다.
let imageUri = 'http://~~/a.jpg'
let imageWidth = 1080;
let imageHeight = 1920;
let ratio = Dimensions.get('window').height/imageHeight;
return(
<Image
source={{uri: imageUri}}
style={{width: imageWidth * ratio, height: imageHeight * ratio}}
/>
);
동일한 이미지를 여러번 호출 하는 경우 캐시에 담아두는 기능이 있다. 뭐.. 그렇다는데 실험은 안해봤다.
let imageUri = 'http://~~/a.jpg'
Image.queryCache([imageUri]);
Device Rotate
내 폰에 테스트하다가 어쩌다가 가로모드로 바꼇는데, 렌더링이 되지는 않았다. 화면에 전환이 있을 때, 계산해서 강제로 렌더링 시켜버렸다. 강제로 렌더링하는 메소드는 this.forceUpdate();
이다.
componentDidMount(){
Dimensions.addEventListener('change', this.onChangeDimensions);
}
componentWillUnmount(){
Dimensions.removeEventListener('change', this.onChangeDimensions);
}
onChangeDimensions = () => {
this.forceUpdate()
}
componentDidMount()
는 초기에render()
가 실행된 이후에 실행되는 걸로 알고있는데, 이거만 하니까componentWillUnmount
정의가 안됬다고 워닝떠서 추가했다.
Touch event on Image
Image
는 기본적으로 onPress
가 없다. 터치 이벤트를 주고 싶으면 상위에 TouchableHighlight
와 같은 컴포넌트를 두고 거기에 onPress
를 줘야한다.
<TouchableHighlight onPress={this.pressImage} activeOpacity={1}>
<Image
source={{uri: imageUri}}
style={{width: imageWidth * ratio, height: imageHeight * ratio}}
/>
</TouchableHighlight>
Animation on Image
클릭했을 때 서서히 어두워지는 효과를 주고 싶었다. 처음에 타이머 만들어서 직접 구현하려고 했는데 이미 Animated
라는 컴포넌트가 정의가 되어 있었다.
state = {
isShowMenu : false,
animateValue : new Animated.Value(1)
};
pressImage = () => {
this.setState({
isShowMenu: !this.state.isShowMenu
}, () => {
Animated.timing(
this.state.animateValue, {
toValue: this.state.isShowMenu? 0.5 : 1,
duration: 500,
useNativeDriver: true
}).start(()=>{
// Console.log('Wow~')
});
});
}
<TouchableHighlight onPress={this.pressImage} activeOpacity={1}>
<Animated.View style={{opacity: this.state.animateValue}}>
<Image
source={{uri: imageUri}}
style={{width: imageWidth * ratio, height: imageHeight * ratio}}
/>
</Animated.View>
</TouchableHighlight>
Filesystem
기본적으로 Filesystem에 대해서 제어하는 기능은 없고 react-antive-fs
모듈을 받아서 진행해야 한다. 이미지 데이터를 받아서 byte로 찍어되야 되나 한숨쉬다가 downloadFile
메소드 있길래 바로 써봤더니 잘 되지는 않았다. 문제는 퍼미션 문제인 것 같아서 디바이스 설정에서 수동으로 파일시스템 권한 줬더니 잘 된다. 이제 파일시스템 퍼미션 주는 방식에 대해 알아봐야겠다.
import * as RNFS from 'react-native-fs';
let imageUri = 'http://~~/a.jpg'
RNFS.downloadFile({
fromUrl: imageUri,
toFile: '/storage/emulated/0/Download/test.jpg'
}).promise.then((r)=>{
console.log(r);
});
Show menu from bottom
이걸.. Animated
로 구현해야 되나 현타왔다가 react-native-bottom-action-sheet
모듈을 쓰기로 했다. GridView
에서 visible에 state를 주면 깔끔할 것 같다. 그래서 이때까지 했던거 총합해서 메뉴가 보일 때 슈르륵 올라오게 만들었다.
import RNBottomActionSheet from 'react-native-bottom-action-sheet';
import Icon from 'react-native-vector-icons/FontAwesome5';
let saveIcon = <Icon family={'FontAwesome'} name={'save'} color={'#000000'} size={30}/>
let shareIcon = <Icon family={'FontAwesome'} name={'share-alt'} color={'#000000'} size={30} />
let settingIcon = <Icon family={'FontAwesome'} name={'cog'} color={'#000000'} size={30} />
<RNBottomActionSheet.GridView
visible={this.state.isShowMenu}
onSelection={(index, value) => {
this.pressImage();
RNFS.downloadFile({
fromUrl: imageUri,
toFile: '/storage/emulated/0/Download/test.jpg'
}).promise.then((r)=>{
console.log(r);
});
}}
onCancel={()=>{this.pressImage();}}
>
<RNBottomActionSheet.GridView.Item title={'저장하기'} icon={saveIcon} />
<RNBottomActionSheet.GridView.Item title={'공유하기'} icon={shareIcon} />
<RNBottomActionSheet.GridView.Item title={'설정화면'} icon={settingIcon} />
</RNBottomActionSheet.GridView>
잡다한 것들
[1] React-Native에서의 이름은 낙타방식이다.
'Dev-' 카테고리의 다른 글
[Python] 네이버 웹툰과 별점 그리고 언론보도 (0) | 2021.03.14 |
---|---|
[React-Native] 시작하기 (0) | 2020.03.31 |
[Python] Bandizip Updater (3) | 2019.06.11 |
[Python] DNS Packet 구조 코드화 (0) | 2018.07.29 |
[C#] Adobe Flash Player 자동 업데이트 문제와 해결 (0) | 2018.07.29 |
블로그의 정보
정윤상이다.
담배맛구마