리액트 네이티브[React Native] 튜토리얼 번역: https://wonhada.com/?docs=%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8Creact-native-0-41

리액트 네이티브[React Native] 스터디에서 아래 기획서대로 앱을 만들기로 했습니다.

https://ovenapp.io/project/lyYmCSSN8CJjW3KVlLLTER9iLMeuzx17#Q2Hff

구현된 앱을 캡쳐했습니다.

[[ 소스 코드 ]]

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */


import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Navigator,
  TouchableHighlight,
  ListView,
  Alert,
  Image,
  ScrollView
} from 'react-native';

export default class Test extends Component {
  constructor() {
    super();
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    var secondArr = [];
    for(var i = 1; i <= 100; ++i) secondArr.push({title:'Sample Title' + i, sub:'Write your message here.'});

    var thirdArr = [];
    for(var i = 1; i <= 20; ++i) thirdArr.push({title:'말이다 청춘! ' + i, uri:'https://facebook.github.io/react/img/logo_og.png'});

    this.state = {
      firstSceneDS: ds.cloneWithRows(['모두의 공원', '사진게시판']),
      secondSceneDS: ds.cloneWithRows(secondArr),
      thirdSceneDS: ds.cloneWithRows(thirdArr),
    };
  }

  render() {
    const routes = [
      {title: '모든 게시판', index: 0},
      {title: '모두의 공원', index: 1},
      {title: '사진게시판', index: 2},
      {title: '모두의 공원 - 상세보기', index: 3},
      {title: '사진게시판 - 상세보기', index: 4}
    ];
    return (
      <Navigator
        initialRoute={routes[0]}
        initialRouteStack={routes}
        renderScene={(route, navigator) => {
          if(route.index == 0) {
            return (
              <ListView
                dataSource={this.state.firstSceneDS}
                renderRow={(rowData) =>
                  <TouchableHighlight onPress={() => {
                    if (rowData === "모두의 공원") {
                      navigator.push(routes[1]);
                    } else if (rowData === "사진게시판") {
                      navigator.push(routes[2]);
                    }
                  }}>
                    <View>
                      <View style={{flexDirection:'row', justifyContent:'space-between'}}>
                        <Text style={{padding: 8}}>{rowData}</Text>
                        <Text style={{padding: 8, paddingRight:12}}>&gt;</Text>
                      </View>
                     <View style={{width:'100%', marginTop:8, height:1, backgroundColor:'#ccc'}} />
                    </View>
                  </TouchableHighlight>
                }
              />
            );
          } else if(route.index == 1) { // 모두의 공원 씬
            return (
              <ListView
                style={{backgroundColor:'#fff', width:'100%', height:'100%'}}
                dataSource={this.state.secondSceneDS}
                renderRow={(rowData) =>
                  <TouchableHighlight onPress={() => {
                    routes[3].title = rowData.title;
                    this.state.txt = "힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...\n힘있다 이것이다 인류의 역사를 꾸며 내려온 동력은 바로 이것이다 이성은 투명하되 얼음과 같으며 지혜는 날카로우나 갑\n\n사랑의 풀이 돋고 이상의 꽃이 피고...";
                    navigator.push(routes[3]);
                  }}>
                    <View>
                      <Text style={{padding: 8, fontSize: 15}}>{rowData.title}</Text>
                      <Text style={{paddingLeft:8, marginTop:-8, fontSize: 12, color: '#ccc'}}>{rowData.sub}</Text>
                      <View style={{width:'100%', marginTop:8, height:1, backgroundColor:'#ccc'}} />
                    </View>
                  </TouchableHighlight>
                }
              />
            );
          } else if(route.index == 2) { // 사진게시판 씬
            return (
              <ListView
                style={{backgroundColor:'#fff', width:'100%', height:'100%'}}
                dataSource={this.state.thirdSceneDS}
                renderRow={(rowData) =>
                  <TouchableHighlight onPress={() => {
                    routes[4].title = rowData.title;
                    this.state.uri = rowData.uri;
                    this.state.title = "것이다 이상의 꽃이";
                    this.state.desc = "것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...\n것이다 보라 청춘을! 그들의 몸이 얼마나 튼튼하며...";
                    navigator.push(routes[4]);
                  }}>
                    <View style={{alignItems:'center'}}>
                      <Image
                        style={{width:'100%', height:200, resizeMode:'cover'}}
                        source={{uri: rowData.uri}}
                        />
                      <Text style={{padding:8}}>{rowData.title}</Text>
                    </View>
                  </TouchableHighlight>
                }
              />
            );
          } else if(route.index == 3) { // 모두의 공원 상세보기 씬
            return (
              <View style={{backgroundColor:'#fff', width:'100%', height:'100%'}}>
                <ScrollView>
                  <Text>{this.state.txt}</Text>
                </ScrollView>
              </View>
            );
          } else if(route.index == 4) { // 사진게시판 상세보기 씬
            return (
              <View style={{backgroundColor:'#fff', width:'100%', height:'100%'}}>
                <ScrollView>
                  <Image
                    style={{width:'100%', height:200, resizeMode:'cover'}}
                    source={{uri: this.state.uri}}
                    />
                  <Text style={{padding:8, fontSize:17, fontWeight:'bold'}}>{this.state.title}</Text>
                  <Text style={{padding:8}}>{this.state.desc}</Text>
                  </ScrollView>
              </View>
            );
          }
        }}
        style={{paddingTop: 55}}
        navigationBar={
           <Navigator.NavigationBar
             routeMapper={{
               LeftButton: (route, navigator, index, navState) =>
                {
                  if (index === 0) {
                    return null;
                  } else {
                    return (
                      <TouchableHighlight onPress={() => navigator.pop()}>
                        <View style={{justifyContent:'center', alignItems:'center', width:50, height:'100%'}}>
                          <Text style={{color:'#fff'}}>Back</Text>
                        </View>
                      </TouchableHighlight>
                    );
                  }
                },
               RightButton: (route, navigator, index, navState) =>
                 {
                  if (index === 0) {
                    return null;
                  } else {
                    return (
                      <View style={{flexDirection:'row', justifyContent:'center', alignItems:'center', width:110, height:'100%'}}>
                        <Text style={{color:'#fff'}}>Search</Text>
                        <Text style={{paddingLeft:8, color:'#fff'}}>More</Text>
                      </View>
                    );
                  }
                },
               Title: (route, navigator, index, navState) =>
                {
                  if (index === 0) {
                    return (
                      <View style={{justifyContent:'center', alignItems:'center', width:'75%', height:'100%'}}>
                        <Text style={{color:'#fff'}}>{route.title}</Text>
                      </View>
                    );
                  } else {
                    return (
                      <View style={{justifyContent:'center', height:'100%'}}>
                        <Text style={{color:'#fff'}}>{route.title}</Text>
                      </View>
                    );
                  }
                },
             }}
             style={{backgroundColor: '#333'}}
           />
        }
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('Test', () => Test);