본문 바로가기
안드로이드 웹앱 콘테츠 개발자 양성(국비지원)/HybridApp

HybridApp-React Native 2세대 (Layout 2, ListView를 안쓰고 이미지텍스트 배치)

by 차누감 2020. 1. 21.
반응형

<최종화면> ListView가 있지만 그전에 ListView를 이용하지 않고도 배치하는 방법을 알아보자.


만들기 전에 AVD를 키고, 만들고자 하는 경로에 init하자.

run을 해보자. 우선 화면에 그냥 흰색으로 나올 것이다. ScrollView 밖에 없으므로..

이미지를 보여주기 위해 RN08ListLayout2 폴더에 images 폴더를 만들자. 그리고 거기에 임의로 이미지를 넣자.

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
import React, {Component} from 'react';
import {View, Text, Image, StyleSheet, ScrollView } from 'react-native';
 
export default class MainComponent extends Component{
    constructor(){
        super();
 
        // 대량의 데이터
        this.state={
            datas: [
                {name:"sam", message:"Hello world",img: require('./images/ms_01.png')},
                {name:"robin", message:"Hello rn",img: require('./images/ms_02.png')},
                {name:"kim", message:"Hello react",img: require('./images/ms_03.png')},
                {name:"hong", message:"Hello hybrid",img: require('./images/ms_04.png')},
                {name:"rosa", message:"Hello ios",img: require('./images/ms_05.png')},
                {name:"lee", message:"Hello rom",img: require('./images/ms_07.png')},
                {name:"jack", message:"Hello tom",img: require('./images/ms_08.png')},
                {name:"moana", message:"Hello native",img: require('./images/ms_09.png')},
                
            ],
        };
    }
    render(){
        return(
            <ScrollView style={style.container}>
                {/* 대량의 데이터 배열의 요소개수 만큼 Component를 리턴하는map */}
                {
                    this.state.datas.map(function(element, index){
                        return(
                            <View key={index}>
                                <Image source={element.img}></Image>
                                <View>
                                    <Text>{element.name}</Text>
                                    <Text>{element.message}</Text>
                                </View>
                            </View>
                        );
                    })
                }
            </ScrollView>
            
        );
    }//render method..
   
}//MainComponent class..
 
const style= StyleSheet.create({
    container: {flex:1, padding:16},
});
 

이미지가 쭉 보일 것이다. 아래로 드래그하면 확인 가능하다.

그러나 경고 문구가 뜬다. key 값을 주자.

이제 한 이미지와 텍스트를 이런 식으로 보여줄 것이다. (이런 아이템을 아래로 쭉 배열할 것이다.)

<실행화면>

이미지 클릭 효과를 주기 위해 <View>태그를 <TouchableOpacity>태그로 바꾸자. 그리고 onPress도 주자.

<실행 화면> 클릭했을때 투명으로 바뀌고, 클릭 후 Aler창이 나온다.

이제 클릭했을 때, 해당 이름을 띄워보자.

onPress안에 this.clickItem을 써주면 값을 전달할 방법이 없다.

onPress안에 this.clickItem()괄호를 쓰게 되면 클릭하기도 전에 함수 호출로 인식한다.

그래서 화살표 함수를 써서 그 안에서 값을 전달하면 된다.


<복붙용 코드>

index.js

1
2
3
4
5
6
7
8
9
10
11
/**
 * @format
 */
 
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import Main from './Main';
 
AppRegistry.registerComponent(appName, () => Main);
 
 

Main.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
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
import React, {Component} from 'react';
import {View, Text, Image, StyleSheet, ScrollView, TouchableOpacity } from 'react-native';
 
export default class MainComponent extends Component{
    constructor(){
        super();
 
        // 대량의 데이터
        this.state={
            datas: [
                {name:"sam", message:"Hello world",img: require('./images/ms_01.png')},
                {name:"robin", message:"Hello rn",img: require('./images/ms_02.png')},
                {name:"kim", message:"Hello react",img: require('./images/ms_03.png')},
                {name:"hong", message:"Hello hybrid",img: require('./images/ms_04.png')},
                {name:"rosa", message:"Hello ios",img: require('./images/ms_05.png')},
                {name:"lee", message:"Hello rom",img: require('./images/ms_07.png')},
                {name:"jack", message:"Hello tom",img: require('./images/ms_08.png')},
                {name:"moana", message:"Hello native",img: require('./images/ms_09.png')},
                
            ],
        };
    }
    render(){
        return(
            <ScrollView style={style.container}>
                {/* 대량의 데이터 배열의 요소개수 만큼 Component를 리턴하는map */}
                {
                    this.state.datas.map((element, index)=>{
                        return(
                            // onPress에서 요소를 제어 할 수 없어서 화살표 함수를 이용함. 
                            <TouchableOpacity key={index} style={style.item} onPress={()=>{this.clickItem(index);}}>
                                <Image source={element.img} style={style.itemImg}></Image>
                                <View style={{flexDirection:'column'}}>
                                    <Text style={style.itemName}>{element.name}</Text>
                                    <Text style={style.itemMsg}>{element.message}</Text>
                                </View>
                            </TouchableOpacity>
                        );
                    })
                }
            </ScrollView>
            
        );
    }//render method..
 
    //메소드를 호출하면서 파라미터로 클릭된 아이템의 index번호 받아야함.
    clickItem=(index)=>{
        // 클릭한 아이템의 name값??
        alert(this.state.datas[index].name);
    }
   
}//MainComponent class..
 
const style= StyleSheet.create({
    container: {flex:1, padding:16},
    item:{
        flexDirection:'row',
        borderWidth:1,
        borderRadius:4,
        padding:8,
        marginBottom:12,
    },
    itemImg:{
        width:120,
        height:100,
        resizeMode:'cover',
        marginRight:8,
    },
    itemName:{
        fontSize:24,
        fontWeight:'bold'
 
    },
    itemMsg:{
        fontSize:16,
        fontWeight:'bold'
    },
    
});
 
반응형

댓글