어서와, 개발은 처음이지?

5.React Native 레이아웃 디자인 - 2부 배치(Flex Direction)와 정렬(justify content, align items) 본문

React/React Native

5.React Native 레이아웃 디자인 - 2부 배치(Flex Direction)와 정렬(justify content, align items)

오지고지리고알파고포켓몬고 2018. 7. 26. 17:19


이 글은

5.React Native 레이아웃 디자인 - 1부 flex와 width, height

5.React Native 레이아웃 디자인 - 2부 배치(Flex Direction)와 정렬(justify content, align items)(현재글)

5.React Native 레이아웃 디자인 - 3부 커스텀 버튼

5.React Native 레이아웃 디자인 - 4부 이미지 컴포넌트와 UI 마무리로 구성되어있습니다.



지난 글에서는 View의 width, height와 flex 속성을 이용하여 각 컴포넌트의 영역을 잡아봤습니다.

이번 글에서는 지난 글에서 미처 다루지 못했던 레이아웃 배치와 정렬에 관한 내용을 다뤄보겠습니다.



1.Flex Direction


혹시 지금까지 진행해 오면서 컴포넌트들이 세로로만 쌓였다는걸 눈치채고 계셨나요?

특별히 신경쓰지 않으셨을 수 있지만, 실제 앱은 실습과 다르게 세로 뿐만 아니라 가로로 구성될 필요가 있습니다.


특별출연해주신 학원 동기님들께 감사인사 드립니다


View에서 자식 요소들을 가로, 세로로 쌓기 위해서 Flex Direction 스타일을 사용합니다.

Flex Direction은 row(행), column(열) 속성을 사용할 수 있으며 row가 가로배치, column이 세로배치라고 생각하시면 됩니다.


자식 요소 라는 말에 유의하셔야 합니다. 현재 View에 Flex Direction을 'row'라고 한다면 자식 View들이 가로배치 됩니다.


또한 Flex Direction의 기본속성은 column으로, 여지껏 별도로 명시하지 않았기 때문에 View들이 세로로 쌓이는 모습을 봐왔습니다.

아래의 예를 통해 직접 보겠습니다.

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.item1} />
        <View style={styles.item2} />
        <View style={styles.item3} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row', // 혹은 'column'
  },
  item1: {
    flex: 1,
    backgroundColor: 'red',
  },
  item2: {
    flex: 1,
    backgroundColor: 'yellow',
  },
  item3: {
    flex: 1,
    backgroundColor: 'green',
  },
});

flexDirection이 column일 경우(좌)와 row일 경우(우) 


3개의 자식 View를 flex:1 속성으로 하여 1:1:1 공간을 차지하도록 했습니다.

Flex Direction 설정을 row로 바꾸니 볼리비아 국기가 기니아 국기로 뙇! 바뀌는 모습을 볼 수 있습니다.



2.Align Items


다음은 정렬입니다. 좌우로 정렬 할 때 그 정렬요.


Align Items는 배치방향(Flex Direction)으로부터 수직한 정렬을 뜻합니다. column(세로 배치)라면 가로 정렬을 뜻하고, row(가로 배치)라면 세로 정렬을 뜻합니다.

flex-start, center, flex-end, stretch, baseline의 5가지 속성을 가지고 있습니다.


flex-start는 가로 정렬을 기준으로 좌측(시작점), center는 가운데, flex-end는 우측(끝점)을 뜻합니다.

stretch는 정렬 방향의 크기를 지정하지 않았을 때 flex-start 지점부터 flex-end지점까지 쭉 늘리는 속성입니다.


그래서 Flex Direction이 column일 경우 Align Items는 가로 정렬이 되고, row일 경우 세로 정렬이 되겠습니다.

가로 정렬은 익숙하실테니 세로 정렬(flexDirection: 'row') 예제를 보시겠습니다.


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.item1}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection:'row',
    alignItems:'flex-start',
  },
  item1: {
    width:50,
    height:50,
    backgroundColor: 'red',
  },
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection:'row',
    alignItems:'center',
  },
  item1: {
    width:50,
    height:50,
    backgroundColor: 'red',
  },
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection:'row',
    alignItems:'flex-end',
  },
  item1: {
    width:50,
    height:50,
    backgroundColor: 'red',
  },
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection:'row',
    alignItems:'stretch',
  },
  item1: {
    width:50,
    //height:50, // stretch는 정렬 방향의 값을 지정해주지 않아야 합니다
    backgroundColor: 'red',
  },
});

좌측부터 flex-start, center, flex-end, stretch


특별히 유의해야 할 점이라면 stretch 속성을 사용하기 위해서는 정렬 방향의 크기를 지정해주지 않아야 적용 된다는 부분이 있습니다.



3.Justify Content


Align Items가 Flex Direction으로부터 수직한 정렬이였다면 Justify Content는 수평한, 즉 Flex Direction의 진행 방향과 같은 방향으로 정렬됩니다.

단, Justify Content는 Align Items와 약간 다른 속성을 가지고 있습니다.


flex-start, center, flex-end는 동일하지만 space-between, space-around라는 속성을 가지고 있습니다.

space-between은 양쪽 정렬, space-around는 공백이 있는 양쪽 정렬이라고 생각하시면 됩니다.



Flex Direction의 진행 방향과 정렬 방향이 같다는 점 빼고 기본속성은 동일하게 동작합니다.

그렇다면 space-between과 space-around는 어떤 모습일까요?

아래 코드와 함께 보시겠습니다.

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.item1} />
        <View style={styles.item2} />
        <View style={styles.item3} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'space-between',
  },
  item1: {
    width:50,
    height:50,
    backgroundColor: 'red',
  },
  item2: {
    width:50,
    height:50,
    backgroundColor: 'yellow',
  },
  item3: {
    width:50,
    height:50,
    backgroundColor: 'green',
  },
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'space-around',
  },
  item1: {
    width:50,
    height:50,
    backgroundColor: 'red',
  },
  item2: {
    width:50,
    height:50,
    backgroundColor: 'yellow',
  },
  item3: {
    width:50,
    height:50,
    backgroundColor: 'green',
  },
});


space-between(좌)과 space-around(우)


어떤가요? 둘의 차이가 보이시나요?

space-between은 양 끝을 기점으로 요소간의 거리를 균등하게 정렬 하고, space-around는 공백을 포함한 상태로 균등하게 정렬합니다.

마치 각 영역을 분할(화면에선 3등분)하고 가운데 정렬을 한 것 같은 모양이네요.


양 끝을 기준으로 균등하게 정렬하는 이 속성을 지원하게 해준 분께 맥주라도 한 잔 사야합니다.

css를 하면서 저런 배치를 하기위해 골치 아팠던 것으로 기억하는데, 이를 응용하면 친구목록 같은 ui에 유용하게 사용할 수 있습니다.

양쪽 정렬이기 때문에 이름이나 대화명의 길이가 바뀌어도 배치가 변하지 않는 모습을 보이고 있습니다.

물론 글자 수가 늘어나면 ...으로 보이도록 처리하는 속성도 있습니다.

하지만 그건 다음에 얘기하도록 해요 :)


코드는 아래와 같습니다.


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.header} />
        <View style={styles.content}>

          <View style={styles.elem}>
            <View style={styles.userInfo}>
              <View style={styles.profile} />
              <Text style={styles.name}>윾또막</Text>
            </View>
            <View style={styles.userComment}>
              <Text>대화명을 입력하세요</Text>
            </View>
          </View>

          <View style={styles.elem}>
            <View style={styles.userInfo}>
              <View style={styles.profile} />
              <Text style={styles.name}>저커버그</Text>
            </View>
            <View style={styles.userComment}>
              <Text>정말 맥주라도 한 잔 사는게 어떻겠니?</Text>
            </View>
          </View>

        </View>
        <View style={styles.footer} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    height:60,
    backgroundColor:'green',
  },
  footer: {
    height:60,
    backgroundColor:'red',
  },
  content: {
    flex:1,
  },

  elem: {
    width: '100%',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    borderColor:'#eee',
    borderBottomWidth:0.5,
    padding: 5,
  },
  userInfo: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  userComment: {
    padding:8,
    backgroundColor:'yellow',
    borderRadius:5,
  },
  profile: {
    width: 50,
    height: 50,
    borderRadius: 25,
    backgroundColor: 'yellow',
  },
  name: {
    paddingLeft: 10,
  }
});


이미 눈치채신 분도 계시겠지만 저 elem이라는 부분을 떼다가 component로 만들면 재사용하기에 아주 유용하겠죠?

이 글에서는 다루지 않을테니 실력 향상을 위해 직접 해보시길 바라겠습니다!



4.요약


1. Flex Direction

* 가로, 세로 배치는 Flex Direction 스타일로 설정

* 가로 배치는 row, 세로 배치는 column이고 기본 값은 column


2. Align Items

* Align Items는 Flex Direction과 수직한 방향으로 정렬

* flexDirection: 'column'에서 Align Items는 가로 정렬, flexDirection: 'row'에서 Align Items는 세로 정렬을 뜻함

* flex-start, center, flex-end, stretch 속성을 가짐 


3. Justify Content

* Justify Content는 Flex Direction과 동일한 방향으로 정렬

* flexDirection: 'column'에서 Justify Content는 세로 정렬, flexDirection: 'row'에서 Justify Content는 가로 정렬을 뜻함

* flex-start, center, flex-end, space-between, space-around 속성을 가짐

* space-between 만든 사람한테 맥주 사줘야함



5.마무리


이번 글에서는 지난 글 이어 컴포넌트의 배치와 정렬에 대해서 알아봤습니다.

다음 글에서는 버튼 컴포넌트를 직접 제작하고 UI를 배치하는 것으로 헤이카카오 시작화면 구현을 해보겠습니다.


Comming Soon!

10 Comments
댓글쓰기 폼