2019년 11월 10일 일요일

react native 기본 예제 따라하기 2 (UI)

1. flex 사용

flex는 화면 비율
<View style={styles.container}>
<View style={styles.case1} />
<View style={styles.case2} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
case1: {
flex: 1,
backgroundColor: 'red',
},
case2: {
flex: 1,
backgroundColor: 'green',
},
}

container에 뷰에 2개의 case 뷰를 만듦
container는 가장 밖에 있는 화면이고 1개가 있기 때문에 현재는 전체 화면으로 보여진다. 그 container속에는 2개의 case가 있는데 각각 1:1의 비율로 존재한다.

flex를 가로의 비율로 사용하고 싶으면
flexDirection: 'row',

flex의 수직 정렬 방법을 설정하고 싶으면 alignItems를 사용
flex-start, center, flex-end, stretch, baseline의 5가지 속성을 가지고 있다.

flex의 수평 정렬 방법을 설정하고 싶으면 justifyContent를 사용
flex-start, cent, flex-end, space-between, space-around의 속성을 가지고 있다.

2. width, height 사용

flex는 전체 비율이면 width와 height는 각각 높이와 넓이를 설정할 수 있다.
상대값(%) 또는 절대값으로 정의가 가능하다.
import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<View style={styles.case1} />
<View style={styles.case2} />
<View style={styles.case3} />
<View style={styles.case4} />
<View style={styles.case5} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
case1: {
width:100,
height:100,
backgroundColor: 'red',
},
case2: {
width:50,
height:100,
backgroundColor: 'green',
},
case3: {
width:150,
height:70,
backgroundColor: 'blue',
},
case4: {
width:"100%",
height:70,
backgroundColor: 'black',
},
case5: {
width:"50%",
height:"50%",
backgroundColor: 'yellow',
},
});


3. TouchableOpacity

기본 Button은 각 플랫폼에 따라 모양이 다르기 때문에 UI 조절에 제한적이다.
이를 해결하기 위해 TouchableOpacity라는 컴포넌트를 사용한다.
-> 터치 이벤트를 사용할 수 있는 View

4. defaultProps

부모 컴포넌트에서 속성을 입력하지 않았을 때 기본 값으로 동작함
static defaultProps = {
title: 'untitled',
buttonColor: '#000',
titleColor: '#fff',
onPress: () => null,
}

5. Image

source는 외주 주소를 통해 이미지를 가져오고
require는 로컬 경로를 통해 이미지를 가져온다.

resizeMode는 이미지의 크기를 자동으로 조절해준다.
cover, contain 속성이 있는데 주로 contain을 사용한다.
(cover는 가로 세로 중 좁은 부분이 100%를 차지할때 까지,
 contain은 가로 세로 중 넓은 부분이 100%를 차지할 때 까지 -> 가로가 좁고 세로가 긴 이미지는 세로의 기준을 잡음)
render() {
return (
<View style={styles.container}>
<Image
style={{height:'100%',width:'100%',resizeMode:'contain'}}
source={require('./img.jpeg')}/>
</View>
);
}




6. 최종

App.js
import React, {Component} from 'react';
import {StyleSheet, Text, View, Image} from 'react-native';
import CustomButton from './CustomButton';
type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.header} />
        <View style={styles.title}>
          <Text style={{fontSize:35,color:'white'}}>새로운 일상의 시작{'\n'}지금 카카오미니를{'\n'}연결해보세요.</Text>
        </View>
        <View style={styles.content}>
          <Image
            style={{height:'100%',width:'100%',resizeMode:'contain'}}
            source={require('./img.png')}/>
        </View>
        <View style={styles.footer}>
          <CustomButton
            buttonColor={'#444'}
            title={'회원가입'}
            onPress={() => alert('회원가입 버튼')}/>
          <CustomButton
          buttonColor={'#023e73'}
          title={'로그인'}
          onPress={() => alert('로그인 버튼')}/>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    backgroundColor: 'black',
  },
  header: {
    width:'100%',
    height:'5%',
    backgroundColor: 'black',
  },
  title: {
    width:'100%',
    height:'18%',
    justifyContent: 'center',
    backgroundColor: 'black',
  },
  content: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingBottom:30,
    backgroundColor: '#d6ca1a',
  },
  footer: {
    width:'100%',
    height:'20%',
    //backgroundColor: '#1ad657',
  },
});

CustomButton.js
import React, { Component } from 'react';
import {
  TouchableOpacity,
  Text,
  StyleSheet,
} from 'react-native';

export default class CustomButton extends Component{
  static defaultProps = {
    title: 'untitled',
    buttonColor: '#000',
    titleColor: '#fff',
    onPress: () => null,
  }

  constructor(props){
    super(props);
  }

  render(){
    return (
      <TouchableOpacity style={[
        styles.button,
        {backgroundColor: this.props.buttonColor}
      ]}
      onPress={this.props.onPress}>
        <Text style={[
          styles.title,
          {color: this.props.titleColor}
        ]}>{this.props.title}</Text>
      </TouchableOpacity>
    )
  }
}

const styles = StyleSheet.create({
  button: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    marginBottom: 10,
    borderRadius: 5,
  },
  title: {
    fontSize: 15,
  },
});



참조:
https://yuddomack.tistory.com/entry/6React-Native-Navigation-%EA%B8%B0%EC%B4%88-2%EB%B6%80-%ED%99%94%EB%A9%B4-%EB%93%B1%EB%A1%9D-%ED%99%94%EB%A9%B4-%EC%9D%B4%EB%8F%99

https://hoony-gunputer.tistory.com/175

https://dev-yakuza.github.io/ko/react-native/react-navigation/











2019년 11월 9일 토요일

react native 기본 예제 따라하기 1-1

1. react native cli에서 expo-cli를 사용하기로 함

react native cli는 자바스크립트 말고도 네이트브 언어를 사용할 수 있다. 근데 어차피 지금 상황에서는 java나 object C를 사용할 계획이 없기 때문에 expo-cli를 사용하기로함

2. expo-cli 설치

npm install expo-cli --global
expo init <project name>
cd project name
expo start

이렇게 생성하고 실행하면 웹페이지가 로딩된다.
여기서 run on Android device/emulator 또는 run on IOS simulator를 클릭하면 된다.
스마트폰을 컴퓨터에 연결하고 각자 os에 맞게 실행


3. 후기

react native cli를 세팅할 때는 안되는 것도 많고 시간이 좀 걸렸는데 expo-cli는 상대적으로 쉽게 환경세팅 및 실행할 수 있었다. 저번에 예제로 연습했던 js파일들을 그대로 가지고 와서 실행했는데 잘 실행됨.

2019년 10월 27일 일요일

구글 블로그에 소스코드 삽입하기

1. http://hilite.me/ 에서 소스코드 입력

2. HTML 복사

3. 구글 블로그에서 글 쓰기

4. 상단에 있는 HTML버튼 클릭

5. HTML 소스 붙여넣기


react native 기본 예제 따라하기 1

0. 안드로이드 스튜디오, 자바 설치
https://developer.android.com/studio/
설치 시 아래 항목을 체크
  • Android SDK
  • Android SDK Platform
  • Performance (Intel ® HAXM)
  • Android Virtual Device
환경 변수 설정
ANDROID_HOME
C:\Users\User\AppData\Local\Android\sdk


1. react-native-cli 설치

npm install -g react-native-cli

-g는 global이라는 뜻으로 해당 프로젝트에 적용하는 것이 아닌 전역 범위에 적용함


2. 프로젝트 생성

react-native init [프로젝트 명]


3. 프로젝트 실행

cd [프로젝트 명]
react-navtive run-android


오류
폴더 생성
android/app/src/main/assets

명령어 실행 
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

또는

react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res



이때 새로운 창이 로딩된다. 이 창은 프로젝트의 디버그 서버가 되어서 코드 변경 시 새롭게 빌드를 할 필요 없이 자동으로 적용된다.

프로젝트의 구조
. ├── App.js ├── android/ ├── app.json ├── index.js ├── ios/ ├── node_modules/ ├── package.json └── yarn.lock

app.js를 살펴보면 코드와 컴포넌트가 XML문서처럼 결합 되어있는 것을 볼 수 있음
-> JSX라 부름 

리액트 프로젝트는 index.js로 시작된다. 이것은 추후에 앱 구조에 따라 수정할 수 있다.

4. app.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
import React, {Component} from 'react';
import {StyleSheet, Button, View} from 'react-native';
import TestComponent from './TestComponent';

const datas = [
  {id:"gdHong",count:0,color:"red"},
  {id:"ksYu",count:0,color:"green"},
  {id:"ssLee",count:0,color:"blue"},
];
type Props = {};
export default class App extends Component<Props> {
  constructor(props){
    super(props);
    this.state={datas:datas};
  }

  _updateCount(idx){
    const newDatas = [...this.state.datas];
    newDatas[idx].count = newDatas[idx].count + 1;
    // newArray[idx].count++;

    this.setState({datas:newDatas});
  }

  render() {
    return (
      <View style={styles.container}>
        {
          this.state.datas.map((data, index) => {
            return(
              <TestComponent
                key={data.id}
                id={data.id}
                color={data.color}
                title={data.count.toString()}
                updateCount={this._updateCount.bind(this, index)}/>
            )
          })
        }
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
});




export default class App extends Component<Props>
리액트를 사용하기 위해서는 Component<Props>를 상속 받아야함

this.state={datas:datas};
위에서 정의한 datas를 state로 사용하기위해 등록함

_updateCount(idx){
const newDatas = [...this.state.datas];
newDatas[idx].count = newDatas[idx].count + 1;
// newArray[idx].count++;
this.setState({datas:newDatas});
}
datas를 복사한 뒤 count를 +1해줌
this.setState를 사용하여 변경 값을 다시 state로 등록하고 랜더링을 다시 해준다.


<View style={styles.container}>
이 Component안에서 자바스크립트 객체를 사용하기 위해서는 {}를 사용해야함



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
render() {
    return (
      <View style={styles.container}>        {
          this.state.datas.map((data, index) => {
            return(
              <TestComponent
                key={data.id}
                id={data.id}
                color={data.color}
                title={data.count.toString()}
                updateCount={this._updateCount.bind(this, index)}/>            )
          })
        }
      </View>    );
  }
}
랜더링을 할 부분
updateCount={this._updateCount.bind(this, index)}/>
현재 _updateCount는 현 클래스의 this.state를 참조하기 떄문에 this를 넣어줌
(만약 this를 사용하지 않는다면 TestComponent에 있는 state를 참조하게 됨)
index는 함수에서 지정한 파라미터



4. TestComponent 추가


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React, { Component } from 'react';
import {
  View,
  Button,
  Text,
} from 'react-native';

export default class TestComponent extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return(
      <View>
        <Text>{this.props.id} 버튼</Text>
        <Button
          color={this.props.color}
          title={this.props.title}
          onPress={this.props.updateCount}/>
      </View>
    )
  }
}



this.props들이 하위 컴포넌트에서 사용하게 됨
-> 하위 컴포넌트에서 사용할 어트리뷰트들을 지정해둠
(껍데기? 같은 느낌??)




참고 : 
https://yuddomack.tistory.com/entry/4React-Native-State%EC%99%80-Props-2%EB%B6%80Props?category=754156

flutter 기본 개념 1

  Scaffold  - 화면 뼈대 역할  - 기본적으로 AppBar body floatingActionButton 같은걸 배치해줌  return Scaffold (       appBar : AppBar ( title : const Text ...