React-Native 공부일지#7) 자원과 아이콘 사용하기
자원 : 앱에 포함하여 배포하는 이미지 폰트 아이콘 등의 파일
=> 통신이 끊어지는 오프라인 상황 또한 염두해두어야 한다.
즉, 필수 자원은 앱에 포함하여 배포해야한다.
ImageBackground 코어 컴포넌트 사용하기
import {ImageBackground} from "react-native"; // 리액트에서 제공하는 코어컴포넌트 import
해당 컴포넌트를 사용하는 방식은 아래와 같다.
<ImageBackground style={styles.display} source={require('./assets/image/test.jpg')}/>
React-native에서 위와 같은 'Image' 라는 단어가 포함된 컴포넌트는 항상 source 속성에 require을 사용하여 읽는 방식으로 파일을 설정해야한다.
Node.js 에서 기본으로 제공하는 require API는 대상 파일이 이미지일 경우, base64로 인코딩한 문자열을 반환한다.
이는 곧 React-native앱 에서의 이미지 파일은 자바스크립트의 코드에 삽입된 형태로 배포된다.
결과적으로 위 코드는 이미지 파일 자원은 별도의 파일이 아닌 소스코드에 삽입된 형태로 배포된다는 것을 보여준다.
추가적으로 이미지를 다루는 컴포넌트는 반드시 화면에 출력될 크기 (width 와 height 속성 값)를 정해줘야하는데, 해당 컴포넌트는 화면의 배경을 다룰 때 사용하므로 flex : 1 을 사용하여 전체화면에 맞추었다.
import React from 'react';
import {SafeAreaView,StyleSheet,Text} from 'react-native';
import {ImageBackground} from "react-native";
const App = () => {
return (
<SafeAreaView style={styles.display}>
<Text>Hi Hello! </Text>
<ImageBackground style={styles.display} source={require('./assets/image/test.jpg')}/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
display : {
flex : 1
}
});
export default App;
해당 컴포넌트는 <View> 컴포넌트와 같이 자식 컴포넌트를 생성할 수 있다.
Image 코어 컴포넌트
ImageBackground 코어 컴포넌트와는 다르게 자식 컴포넌트를 가질 수 없다.
형태는 다음과 같으며 만약 원격 서버에서 파일을 받아 렌더링 하는 경우에는 source에 이미지 파일 웹 주소를 적으면 된다.
<Image source={{uri: avatarUri}} style={[styles.image]}/> // avatarUri === https://www.~~~~
import React from 'react';
import {SafeAreaView,StyleSheet,Text} from 'react-native';
import {ImageBackground} from "react-native";
import {Image} from 'react-native';
import * as D from './data'
const App = () => {
const avatarUri = D.randomAvatarUrl();
return (
<SafeAreaView style={styles.display}>
<Text style={styles.default}>Hi Hello! </Text>
<ImageBackground style={styles.display} source={require('./assets/image/test.jpg')}/>
<Image source={{uri: avatarUri}} style={[styles.image]}/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
display : {
flex : 1
},
default : {
fontFamily: 'ChosunCentennial_ttf'
},
image :{
width : 50,
height : 50,
borderRadius: 1
}
});
export default App;
폰트 적용
react-native 0.69.0 부터는 link 명령어를 삭제하고 autolink를 지원한다고 한다. 말 그대로 link하기 위한 작업이나 명령어를 삭제하고 대신에 자동으로 적용한다는 의미이다.
link 란 RN에 적용한 src/assets/fonts 폴더에 있는 폰트들을 네이티브 쪽에 복사해주는 기능이다
0.69.0 버전 이전에는 npx react-native link 라는 명령어로 링크를 했지만 이후에는 자동링크 기능을 지원하여 그럴 필요가 없어졌다.
필자의 개발 환경은 안드로이드에 초점이 맞춰져있으므로 안드로이드 기준에서 설명한다. (아이폰은 조금 다르다.)
src/assets/fonts 폴더 안에 원하는 폰트를 집어넣어준다. (폴더가 없으면 만들면 된다.)
그리고 위에 android 폴더에도 app/src/main/assets/fonts 폴더에 똑같이 넣어준다.
const styles = StyleSheet.create({
display : {
flex : 1
},
default : {
fontSize: 50,
fontFamily: 'DancingScript-Bold',
fontWeight : '300'
},
image :{
width : 50,
height : 50,
borderRadius: 1
}
});
폰트를 적용할 텍스트에 들어갈 속성에 이름을 명시해준다.
<Text style={styles.default}>Hello!</Text>
에뮬레이터를 refresh하거나 껏다 키면 위와 같이 적용된 모습을 볼 수 있다.
import React from 'react';
import {Alert, SafeAreaView, StyleSheet, Text} from 'react-native';
import {ImageBackground} from "react-native";
import {Image} from 'react-native';
import * as D from './data';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
import {Colors} from 'react-native-paper';
import Color from 'color';
const App = () => {
const avatarUri = D.randomAvatarUrl();
const onIconPressed = () => Alert.alert('Icon Pressed');
return (
<SafeAreaView style={styles.display}>
<Text style={styles.default}>Hello!</Text>
<ImageBackground style={styles.display} source={require('./assets/image/test.jpg')}/>
<Image source={{uri: avatarUri}} style={[styles.image]}/>
<Icon name="home" size={50} color={Colors.lightBlue200} onPress={onIconPressed}/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
display : {
flex : 1
},
default : {
fontSize: 50,
fontFamily: 'DancingScript-Bold',
fontWeight : '300'
},
image :{
width : 50,
height : 50,
borderRadius: 1
}
});
export default App;
전체코드이다.
다만 리액트에서 폰트는 CSS에서와 다르게 부모 컴포넌트에 적용하면 자식 컴포넌트에게 모두 전달되지 않으므로 일일이 텍스트가 들어가는 곳에 폰트 스타일을 적용해야한다.
참고 : https://velog.io/@tjdgus0528/React-Native-Fonts-%EC%84%A4%EC%A0%95
[ React Native ] Fonts 설정
리액트 네이티브에서 외부 폰트를 추가하고 설정하는 방법에는 직접적으로 폰트를 파일을 추가하고 설정하는 방법 라이브러리 사용 이 있다. 나는 라이브러리 사용으로 인한 환경 세팅 중 에러
velog.io
벡터 아이콘 적용하기
벡터 아이콘도 마찬가지로 리액트 네이티브에서 link 해야하는 자원 중 하나지만 자동 링크로 인해 asset 폴더에 잘 관리해주면 된다. 앞서서 설치한 @type/react-native-vector-icons 패키지를 갖고 아이콘을 만들어보고자 한다.
설치한 패키지는 하위에 많은 아이콘 세트를 갖고 있는데, 아이콘을 사용하고 싶으면 해당 아이콘을 포함하는 세트를 import 해주면 된다.
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
// MaterialCommunityIcons === 아이콘 세트이름
아이콘 컴포넌트 활용은 다음과 같다.
<Icon name="아이콘_이름" size={크기} color=색상 onPress={콜백함수}/>
위에서 패키지를 import 하고 원하는 아이콘 이름을 검색해서 찾은 다음 코드에 적절히 배치하면
다음과 같이 home 아이콘이 적용되었다.
맥은 적용 방법 및 환경이 또 다르므로 조심하자
컴포넌트 배치 관련 스타일 속성 탐구
위와 같이 components 폴더에 TopBar - Content - BottomBar 이렇게 구성이 동일한 3가지 컴포넌트들을 생성하였다.
import React from 'react';
import {StyleSheet,View,Text} from "react-native";
import {Colors} from "react-native-paper";
import * as D from '../data';
const title = 'CopyMe';
function CopyMe() {
return (
<View style={styles.view}>
<Text style={[styles.text]}>{title}</Text>
</View>
)
}
const styles = StyleSheet.create({
view:{
padding : 5,
backgroundColor: Colors.lightBlue200
},
text : {
fontSize: 20,
color: 'white'
}
})
export default CopyMe;
각 컴포넌트들의 기본이 되는 코드이다. 각 컴포넌트는 가로는 전부 차지하고 세로는 짧은 bar 형태를 띈다.
각 컴포넌트를 화면에 배치하면 다음과 같다.
이때 content 컴포넌트의 길이를 flex : 1 로 두었을 때와 height : '100%' 로 두었을 때 두가지 모두 경우를 확인해보겠다.
두 경우의 차이로 보아 알수 있는 사실은 flex 속성은 부모 컴포넌트의 높이 중에 여분이 있을 때 나머지 컴포넌트를 고려하면서 여분을 모두 가져오지만 height : 100% 는 남은 여분을 다른 컴포넌트 고려 없이 전부 가져옴을 알 수 있다.
다음은 content 의 flex 비율을 각각 다르게 해보았다.
return (
<View style={styles.view}>
<Text style={[styles.text]}>{title}</Text>
<View style={{flex:0,backgroundColor: Colors.amber900}}>
<Text> Flex : 0</Text>
</View>
<View style={{flex:1,backgroundColor: Colors.amber800}}>
<Text> Flex : 1</Text>
</View>
<View style={{flex:2,backgroundColor: Colors.amber700}}>
<Text> Flex : 2</Text>
</View>
<View style={{flex:4,backgroundColor: Colors.amber900}}>
<Text> Flex : 4</Text>
</View>
</View>
)
content.tsx 를 다음과 같이 구성하고 결과를 확인 해보자
content 컴포넌트가 padding과 flex : 0 (부모의 남은 공간을 할당하지 않기로 하였으므로 텍스트 태그가 가진 자기 자신만의 크기를 고수) 이 가진 공간을 제외하고 할당 받은 영역을 flex : 1,2,4 가 각각 1 : 2 : 4 비율로 나눠갖는 모습이다.