[React Native] 인스타그램 UI 만들기 #4
익스랩 최고 관리자
·2020. 1. 9. 23:19
리액트 네이티브(React Native)로 인스타그램 UI를 구현하는 네 번째 강의입니다. 이번에는 프로필 화면을 구현합니다. 이 포스팅은 아래 무료 동영상 강의를 참고하여 작성하였습니다.
상단바 수정하기
탭 화면마다 상단바가 다르기 때문에 수정해야합니다. 현재는 모든 탭 화면에서 같은 상단바가 보입니다.
먼저 ./Components/MainScreen.js
파일을 수정합니다. navigationOptions
의 header
에 null 을 입력합니다.
export default class MainScreen extends Component {
static navigationOptions = {
header: null
}
// (...)
그다음 ./Components/AppTabNavigator/HomeTab.js
파일을 수정합니다. Header, Left, Right, Body
를 추가로 import 합니다.
import { Container, Content, Icon, Thumbnail, Header, Left, Right, Body } from 'native-base';
그리고 render()
함수를 수정합니다. <Container>
아래에 <Header>
를 추가합니다.
export default class HomeTab extends Component {
render() {
return (
<Container style={style.container}>
<Header>
<Left><Icon name='ios-camera' style={{ paddingLeft:10 }}/></Left>
<Body><Text>Instagram</Text></Body>
<Right><Icon name='ios-send' style={{ paddingRight:10 }}/></Right>
</Header>
// (...)
여기까지 작업하고 확인해봅니다. 확인해보면 나머지 탭 화면에는 헤더가 사라졌습니다. 그리고 HomeTab 화면에는 헤더가 생겼습니다.
프로필 페이지 헤더 만들기
./Components/AppTabNavigator/ProfileTab.js
를 수정합니다. Image
와 Container, Content, Header, Left, Body, Right, Button
를 추가로 import 합니다.
import { View, Text, StyleSheet, Image } from 'react-native';
import { Icon, Container, Content, Header, Left, Body, Right, Button, Image } from 'native-base';
그다음 render()
함수를 수정합니다. 프로필 화면에도 <Header>
를 추가합니다.
export default class ProfileTab extends Component{
render() {
return (
<Container style={{ flex:1, backgroundColor: 'white'}}>
<Header>
<Left><Icon name="md-person-add" style={{ paddingLeft:10 }} /></Left>
<Body><Text>anpigon</Text></Body>
<Right><EntypoIcon name="back-in-time" style={{ paddingRight:10, fontSize: 32 }} /></Right>
</Header>
</Container>
);
}
// (...)
다음은 여기까지 작업한 화면입니다. 헤더 좌우에 아이콘이 생겼습니다.
<Header>
바로 아래에 다음 코드를 입력합니다. 프로필 이미지, 포스팅 수, 팔로워 수, 팔로잉 수를 출력합니다. 바로 아래에 프로필 수정 버튼과 설정 버튼이 위치하고 있습니다. 그리고 그 아래에 이름과 프로필 정보가 출력됩니다.
<Content>
<View style={{flexDirection:'row', paddingTop:10}}>
<View style={{flex:1, alignItems:'center'}}>
<Image source={{ url: 'https://steemitimages.com/u/anpigon/avatar' }}
style={{width:75, height:75, borderRadius:37.5}}/>
</View>
<View style={{flex:3}}>
<View style={{flexDirection:'row', justifyContent:'space-around'}}>
<View style={{alignItems:'center'}}>
<Text>167</Text>
<Text style={{fontSize:10, color:'gray'}}>posts</Text>
</View>
<View style={{alignItems:'center'}}>
<Text>346</Text>
<Text style={{fontSize:10, color:'gray'}}>follower</Text>
</View>
<View style={{alignItems:'center'}}>
<Text>192</Text>
<Text style={{fontSize:10, color:'gray'}}>following</Text>
</View>
</View>
<View style={{flexDirection:'row'}}>
<Button bordered dark
style={{flex:4, marginLeft:10, justifyContent:'center', height:30, marginTop:10}}>
<Text>Edit Profile</Text>
</Button>
<Button bordered dark small icon
style={{flex:1, marginRight:10, marginLeft:5, justifyContent:'center', height:30, marginTop:10}}>
<Icon name="settings" />
</Button>
</View>
</View>
</View>
<View style={{paddingHorizontal:10, paddingVertical:10}}>
<Text style={{fontWeight:'bold'}}>안피곤</Text>
<Text>Lark | Computer Jock | Commercial Pilot</Text>
<Text>www.steemit.com/@anpigon</Text>
</View>
</Content>
아래는 여기까지 작업한 화면입니다.
스팀잇 프로필 정보 출력하기
스팀잇 API 서버에서 계정 정보를 가져오는 함수를 구현합니다. 계정 정보를 가져오기 위해서 database_api.get_accounts
API를 사용하였습니다.
fetchAccount(username) {
const data = {
id: 3,
jsonrpc: "2.0",
method: "call",
params: [
"database_api",
"get_accounts",
[[username]]
]
};
return fetch('https://api.steemit.com', {
method: 'POST',
body: JSON.stringify(data)
})
.then(res => res.json())
.then(res => res.result[0])
}
그리고 스팀잇 팔로우 수와 팔로잉 수를 가져오는 함수를 입력합니다. follow_api.get_follow_count
API를 사용합니다.
fetchFollowCount(username) {
const data = {
id: 4,
jsonrpc: "2.0",
method: "call",
params: [
"follow_api",
"get_follow_count",
[username]
]
};
return fetch('https://api.steemit.com', {
method: 'POST',
body: JSON.stringify(data)
})
.then(res => res.json())
.then(res => res.result)
}
그다음 componentWillMount()
를 구현합니다. 그리고 방금 구현한 fetchFollowCount()
함수를 호출합니다. 가져온 계정 정보와 팔로우 수를 state
에 저장합니다. 명성(reputation)도 계산하여 저장합니다.
componentWillMount() {
const username = 'anpigon'; // 내 계정명
this.fetchAccount(username).then(({name, post_count, reputation, json_metadata}) => {
const { profile } = JSON.parse(json_metadata); // JSON 파싱
const log = Math.log(parseInt(reputation.substring(0, 4))) / Math.log(10);
this.setState({
name, // 이름
reputation: Math.max(reputation.length - 1 + log - parseInt(log) - 9, 0) * 9 + 25, // 명성도 계산
postCount: post_count, // 포스팅 수
profile // 프로필 정보
})
});
this.fetchFollowCount(username).then(({following_count, follower_count}) => {
this.setState({
followingCount: following_count, // 팔로잉 수
followerCount: follower_count // 팔로워 수
})
});
}
마지막으로 render()
함수를 수정합니다. 앞에서 가져온 정보들을 출력하기 위해 데이터를 맵핑합니다.
render() {
const {
name,
reputation,
profile,
postCount,
followingCount,
followerCount
} = this.state;
return (
<Container style={{ flex:1, backgroundColor: 'white'}}>
<Header>
<Left><Icon name="md-person-add" style={{ paddingLeft:10 }} /></Left>
<Body><Text>{name}</Text></Body>
<Right><EntypoIcon name="back-in-time" style={{ paddingRight:10, fontSize: 32 }} /></Right>
</Header>
<Content>
<View style={{flexDirection:'row', paddingTop:10}}>
<View style={{flex:1, alignItems:'center'}}>
<Image source={{ url: profile.profile_image }}
style={{width:75, height:75, borderRadius:37.5}}/>
</View>
<View style={{flex:3}}>
<View style={{flexDirection:'row', justifyContent:'space-around'}}>
<View style={{alignItems:'center'}}>
<Text>{postCount}</Text>
<Text style={{fontSize:10, color:'gray'}}>posts</Text>
</View>
<View style={{alignItems:'center'}}>
<Text>{followingCount}</Text>
<Text style={{fontSize:10, color:'gray'}}>follower</Text>
</View>
<View style={{alignItems:'center'}}>
<Text>{followerCount}</Text>
<Text style={{fontSize:10, color:'gray'}}>following</Text>
</View>
</View>
<View style={{flexDirection:'row'}}>
<Button bordered dark
style={{flex:4, marginLeft:10, justifyContent:'center', height:30, marginTop:10}}>
<Text>Edit Profile</Text>
</Button>
<Button bordered dark small icon
style={{flex:1, marginRight:10, marginLeft:5, justifyContent:'center', height:30, marginTop:10}}>
<Icon name="settings" />
</Button>
</View>
</View>
</View>
<View style={{paddingHorizontal:10, paddingVertical:10}}>
<Text style={{fontWeight:'bold'}}>{profile.name} ({reputation.toFixed(2)})</Text>
<Text>{profile.about}</Text>
<Text>{profile.website}</Text>
</View>
</Content>
</Container>
);
}
아래는 여기까지 작업한 화면입니다.
그리고 작업한 코드는 모두 깃허브에 업로드되어 있습니다.
https://github.com/anpigon/rn_instagram_clone
여기까지 읽어주셔서 감사합니다.
script ...
'IT 언어 연구소 > React Native [실습, 예제, 스크랩]' 카테고리의 다른 글
[React Native] 인스타그램 UI 만들기 #3 (0) | 2020.01.09 |
---|---|
[React Native] 인스타그램 UI 만들기 #2 (0) | 2020.01.09 |
[React Native] 인스타그램 UI 만들기 #1 (0) | 2020.01.09 |