React_native

리액트 네이티브 #5_ 인스타그램(Instagram) UI 무작정 따라하기 (2)

Tigercow.Door 2018. 5. 22. 23:26


지난글

리액트 네이티브 #4_ 인스타그램(Instagram) UI 무작정 따라하기 (1)


Github

https://github.com/doorBW/INSTA-by-react-native


안녕하세요. 문범우입니다.

지난 포스팅에서는 인스타그램을 만들기 위해 기본적인 네비게이션 구성을 하고 각 화면으로 넘어가는 단계까지 진행하였습니다.


이번 포스팅에서는 메인화면에 피드를 추가해보는 과정을 진행해보도록 하겠습니다.

이번 포스팅을 통한 결과물은 다음과 같습니다.



1. CardComponent 추가하기.


먼저 각 피드가 될, 새로운 js 파일을 만듭니다.

저는 Components 폴더 내부에 CardComponent.js 라는 이름으로 파일을 만들었습니다.


그리고 CardComponent.js 의 내용으로는 기본 틀만 잡아주었습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
} from 'react-native';
 
class CardCompnent extends Component{
    render(){
        return (
            <View style={style.container}>
                <Text>CardCompnent</Text>
            </View>
        );
    }
}
export default CardCompnent;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
})
cs


이제 HomeTab 에서 해당 CardComponent를 불러와 피드처럼 수정해주어야 합니다. 실질적인 피드의 사진이나 기타 내용은 CardComponent.js 에서 작성해 줄테지만, 우리가 인스타그램에서 보면 하나의 피드만 존재하는게 아니잖아요?

즉, CardComponent.js 는 하나의 피드가 될 것이고, 여러개의 피드를 추가하는건 HomeTab.js 에서 진행하기 때문에, 각 피드의 형태를 HomeTab.js 에서 잡아주어야 합니다.


먼저 HomeTab.js 에서 아래 코드를 통해 CardComponent.js 를 불러옵니다.


import CardComponent from '../CardComponent';


그리고 HomeTab.js 의 본문 내용을 수정하여 CardComponet를 보여주도록 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
    } from 'react-native';
import { Icon, Container, Content } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <CardComponent/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


위의 코드가 현재까지 진행된 HomeTab.js 의 코드입니다.

먼저 9번 줄에서 CardComponent를 import 하였고, 추가적으로 native-base 라이브러리에서 Icon 뿐만 아니라, Container와 Content를 불러왔습니다.

그리고 21번 ~ 25번 줄을 보시면 기존에 있던 HomeTab의 내용을 없애고 Container > Content > CardComponent 형태로 작성하였습니다.

또한 Container 태그에 스타일을 지정해주었고, 32번줄에 작성되어 있는 container 스타일을 보면, 기존에 있던 것에서 flex를 남겨두고 지웠으며, 추가로 backgroundColor를 지정해 주었습니다.


이렇게 하여 시뮬레이터를 확인하면 HomeTab에서 CardComponent가 뜨는 것을 볼 수 있습니다.



2. CardComponent 수정하기


이제 CardComponent.js 로 들어와 수정해보도록 하겠습니다.

먼저, CardComponent에서 사용할 native-base의 요소를 몇가지 추가해보도록 하겠습니다.

우리가 사용할 요소들은 Card, CardItem, Thumnail, Body, Left, Right, Button, Icon 이므로 아래와 같은 코드로 추가합니다.


import { Card, CardItem, Thumnail, Body, Left, Right, Button, Icon} from 'native-base';


이제 각각의 요소들을 활용하여 CardComponent의 내용을 꾸며봅니다.

이전에 먼저 여러분의 프로젝트 폴더에 있는 assets 폴더 안에, 프로필사진으로 쓸 이미지 하나와, 피드 이미지로 사용할 사진 약 3개를 넣어두시면 편합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
} from 'react-native';
 
import { Card, CardItem, Thumbnail, Body, Left, Right, Button, Icon } from 'native-base';
 
class CardCompnent extends Component{
    render(){
        return (
            <Card>
                <CardItem>
                    <Left>
                        <Thumbnail source={require('../assets/beomwoo.jpeg')} />
                        <Body>
                            <Text>Beomwoo</Text>
                            <Text note>2018년 5월 22일</Text>
                        </Body>
                    </Left>
                </CardItem>
            </Card>
        );
    }
}
export default CardCompnent;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
})
cs


위의 CardComponents.js 의 코드를 보시면, 내부에 Card > CardItem > Left > Thumbnail, Body 가 있는 것을 볼 수 있습니다.

먼저 여기서 Thumbnail은 프로필 사진을 의미합니다. 해당 태그의 source 속성에 여러분들의 이미지를 추가시켜 주시면 되고, 해당 이미지는 인스타그램의 프로필처럼 동그라미 형태로 나오게 됩니다.

그리고 Body 내부에 적어준 Text 두개는 사용자 계정과 요일을 나타냅니다.


이제 피드의 상단부를 제작하였으니, 본문, 피드 이미지를 추가해야 합니다.

그러기 위해서 CardItem을 추가하여 코드를 작성합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    Image
} from 'react-native';
 
import { Card, CardItem, Thumbnail, Body, Left, Right, Button, Icon } from 'native-base';
 
class CardCompnent extends Component{
    render(){
        return (
            <Card>
                <CardItem>
                    <Left>
                        <Thumbnail source={require('../assets/beomwoo.jpeg')} />
                        <Body>
                            <Text>Beomwoo</Text>
                            <Text note>2018년 5월 22일</Text>
                        </Body>
                    </Left>
                </CardItem>
                <CardItem>
                    <Image source={require('../assets/react_native.jpg')} style={{height:200, width:null, flex:1}}/>
                </CardItem>
            </Card>
        );
    }
}
export default CardCompnent;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
})
cs


24번 ~ 26번 줄을 보시면 새로운 CardItem 을 추가하여 그 내부에 Image 태그를 통해 피드이미지가 될 사진을 추가하였습니다.

이때, Image 태그를 사용하기 위해 6번 줄과 같이 import 요소를 추가해주어야 합니다.


이제, 피드의 마지막으로 좋아요, 댓글 버튼 등과 좋아요 개수, 본문을 추가해보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    Image
} from 'react-native';
 
import { Card, CardItem, Thumbnail, Body, Left, Right, Button, Icon } from 'native-base';
 
class CardCompnent extends Component{
    render(){
        return (
            <Card>
                <CardItem>
                    <Left>
                        <Thumbnail source={require('../assets/beomwoo.jpeg')} />
                        <Body>
                            <Text>Beomwoo</Text>
                            <Text note>2018년 5월 22일</Text>
                        </Body>
                    </Left>
                </CardItem>
                <CardItem>
                    <Image source={require('../assets/react_native.jpg')} style={{height:200, width:null, flex:1}}/>
                </CardItem>
                <CardItem style={{height:45}}>
                    <Left>
                        <Button transparent>
                            <Icon name='ios-heart-outline' style={{color:'black'}}/>
                        </Button>
                        <Button transparent>
                            <Icon name='ios-chatbubbles-outline' style={{color:'black'}}/>
                        </Button>
                        <Button transparent>
                            <Icon name='ios-send-outline' style={{color:'black'}}/>
                        </Button>
                    </Left>
                </CardItem>
                <CardItem style={{ height:40 }}>
                    <Text>좋아요 101개</Text>
                </CardItem>
                <CardItem>
                    <Text>
                        <Text style={{fontWeight:'900'}}>Beomwoo </Text>
                        #인스타그램 #따라하기 #리액트네이티브</Text>
                </CardItem>
            </Card>
        );
    }
}
export default CardCompnent;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
})
cs


갑작스레 추가된 코드가 좀 길게 보일 수 있지만, 27번 ~ 47번까지, 3개의 CardItem을 추가시키며, 버튼을 포함한 CardItem, 좋아요 개수를 알려주는 CardItem, 본문내용을 보여주는 CardItem 을 추가했을 뿐입니다.

크게 어려운 내용은 아니니 따라오실 수 있을 겁니다. :)


이렇게까지 하고 시뮬레이터를 확인해보면, 



위와 같이 인스타그램의 하나의 피드처럼 완성이 되었습니다.


그런데, 각 피드마다 이미지나, 좋아요 개수는 같지 않습니다.

(물론 아이디나 날짜, 댓글도 서로 다르게 구현되어야 하지만 일단은 따라하기니까... 이미지와 좋아요 개수만 컨드롤 해보겠습니다.)

즉, 여러개의 피드를 추가할텐데, 이때 각각의 피드마다 이미지와 좋아요 개수가 다르게 설정될 수 있도록 코드를 수정해보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    Image
} from 'react-native';
 
import { Card, CardItem, Thumbnail, Body, Left, Right, Button, Icon } from 'native-base';
 
class CardCompnent extends Component{
    render(){
        const images = {
            '1': require('../assets/react_native.jpg'),
            '2': require('../assets/python.jpg'),
            '3': require('../assets/deep_learning.png')
        }
 
        return (
            <Card>
                <CardItem>
                    <Left>
                        <Thumbnail source={require('../assets/beomwoo.jpeg')} />
                        <Body>
                            <Text>Beomwoo</Text>
                            <Text note>2018년 5월 22일</Text>
                        </Body>
                    </Left>
                </CardItem>
                <CardItem>
                    {/* <Image source={require('../assets/react_native.jpg')} style={{height:200, width:null, flex:1}}/> */}
                    <Image source={images[this.props.imageSource]} style={{height:200, width:null, flex:1}}/>
                </CardItem>
                <CardItem style={{height:45}}>
                    <Left>
                        <Button transparent>
                            <Icon name='ios-heart-outline' style={{color:'black'}}/>
                        </Button>
                        <Button transparent>
                            <Icon name='ios-chatbubbles-outline' style={{color:'black'}}/>
                        </Button>
                        <Button transparent>
                            <Icon name='ios-send-outline' style={{color:'black'}}/>
                        </Button>
                    </Left>
                </CardItem>
                <CardItem style={{ height:40 }}>
                    {/* <Text>좋아요 101개</Text> */}
                    <Text>좋아요 {this.props.likes}개</Text>
                </CardItem>
                <CardItem>
                    <Text>
                        <Text style={{fontWeight:'900'}}>Beomwoo </Text>
                        #인스타그램 #따라하기 #리액트네이티브</Text>
                </CardItem>
            </Card>
        );
    }
}
export default CardCompnent;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    }
})
cs


위의 코드를 보시면, 31번줄을 32번 줄과 같이 수정했고, 48번줄을 49번 줄과 같이 수정하였습니다.

수정된 두줄의 코드 모두 어떤 이미지를 넣거나, 숫자를 넣는대신에 {this.props.~} 형태로 입력해주었습니다.

그리고 이미지는 13번 ~ 17번 줄에 집합형태로 추가시켜줌으로써 우리가 어떤 숫자를 넘겨주는지에 따라 이미지가 설정되도록 하였습니다.

이것은 우리가 HomeTab.js 에서 각 피드를 추가할때 ~에 쓰여진 이름으로 데이터를 전달해주면 그 값을 받는 곳을 지정해 준 것입니다.

즉, 우리가 HomeTab.js 에서 CardComponent 를 보여줄때 추가로 imageSource에 진짜 이미지의 경로를 적어주고, likes 에 좋아요의 개수를 적어주면 그 값이 전달되어 보여지게 됩니다.


그럼 HomeTab.js 로 돌아가서 총 3개의 피드를 추가해보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
    } from 'react-native';
import { Icon, Container, Content } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


위와 같이 HomeTab.js 에서 CardComponent 를 3개 추가하고 각각에 따라 설정값을 다르게 주었습니다.


이렇게까지 하면 다음과 같이 어느정도 인스타그램의 첫 화면이 완성되었습니다.



이렇게 하여 인스타그램 UI 따라하기 2번째 포스팅을 마무리 하겠습니다.


오류가 생기거나 추가적으로 궁금한 사항이 있으신 분들은 댓글 또는 공지사항을 통해 이메일이나 카카오톡으로 말씀해주세요 :)

728x90