본문 바로가기

Flex

Flex 레이아웃 잡기 - 제한 레이아웃 (constraintRows, constraintColumns)

플렉스의 레이아웃 컨테이너는 여러가지 종류가 있지만 가장 많이 사용되는 것은 Canvas, Box (VBox, HBox) 일것이다.

기본적으로 Canvas 는 absolute 기반으로 즉 좌표를 기반으로 절대위치를 결정해서 아이템을 배치 하게 되고 Box 계열은 vertical 이나 horozontal 정렬 방식으로 다른 아이템들과의 위치를 판단해서 전체적인 배치를 하게 된다.

어느것이 좋냐는 아빠가 좋냐 엄마가 좋냐 정도의 문제가 될수 있으니 일단 배제 하고..
아래 그림과 같은 레이아웃을 만든다고 가정하고 간단하게 구조를 잡아보자..


클릭해서 보면 상단,하단의 위아래로 나눠진 구조에 아래쪽은 좌,우로 나눠진 형태이다.

일반적인 사이트들의 레이아웃이고 관리자화면을 꾸밀때나 게시판 형식을 만들때 자주 보게 되는 형식일 것이다. (나만 이렇게 만드는건 아니겠지 -ㅅ-;)

상단은 높이가 고정되어있고 하단은 나머지 높이를 차지 하게 된다.
하단에서는 우측은 넓이가 고정되어있고 좌측은 우측을뺀 나머지 넓이를 차지하게 된다.

이런 형태의 레이아웃을 만들기 위해서 일반적으로 생각을 할때 위아래로 배치 되어야 하니까 어플리케이션은 vertical로 레이아웃을 설정하고 상단/하단 구분을 위해서 HBox 를 두개 배치 하고 하단 HBox 내부에 다시 데이터 그리드와 패널을 배치 하는 형태가 될것이다.
만약 데이터 그리드 위쪽에 정보를 보여주거나 설명을 위한 라벨만 하나 들어갈려고 해도 하단 VBox를 추가해서 라벨과 데이터 그리드를 넣어야 한다. 몇개 안되는 구조를 위해서 컨테이너가 꽤나 많이 사용되는 것이다.

이런 방법은 예전에 HTML 페이지에서 테이블로 구조를 만들어본 경험이있는 사람들이 즐겨 쓰는 방법이다. 지금은 HTML도 div를 사용해서 적절하게 겹치지 않도록 레이아웃을 하지만.. 전에는 중첩 테이블을 이용해서 td 안에 테이블 또 td 안에 테이블 이런 형태로 레이아웃을 구성했었다.

그렇게 만들었던 경험이 저런식으로 레이아웃을 만들게 되는 것이다.

중첩 구조로 만들때의 문제점은 Flex3 컨테이너가 모든 이벤트 처리 및 스크롤 등을 전부 가지고 있는 놈이라는 거다. 이벤트는 컨테이너를 따라 계속 버블링 되고 스크롤을 사용하던 사용하지 않던 이미 내부적으로는 맹렬하게 계산해서 처리를 하고 있다.

Flex4 에서는 Group이 추가 되면서 저런 문제가 줄어들겠지만 지금 Flex3를 주력으로 사용하고 있는 입장에서는 아무래도 중첩 구조는 퍼포먼스나 이후의 구조변경을 할때에도 부담이 될 수 밖에 없다.

하지만 브라우저 사이즈에 따라서 유동적으로 변경되는 레이아웃을 좌표계를 기반으로 만들기에는 좀 불편하다.

이 포스트에서 소개 하고자 하는것은 제한 레이아웃 생성자인 constraintRowsconstraintColumns 이다.
absolute 타입의 레이아웃에서 미리 화면을 제한해서 분할 하고 그 제한된 위치를 참고해서 레이아웃을 구성할 수 있게 해준다.
constraintRows는 상하단으로 구분을 할때 사용하고 constraintColumns는 좌우측을 구분할때 사용한다.

<mx:constraintRows>
      <mx:ConstraintRow id="title" height="30"/>
     <mx:ConstraintRow id="content" height="100%"/>
</mx:constraintRows>

이 코드는 absolute 로 정의된 어플리케이션의 공간을 상단을 높이 30 으로 하단은 나머지를 사용하도록 미리 분할한다. 분할된 선은 보이지 않는다 -ㅅ-;

<mx:constraintColumns>
      <mx:ConstraintColumn id="list" width="100%"/>
      <mx:ConstraintColumn id="sideBar" width="200"/>
</mx:constraintColumns>

이 코드는 constraintColumns 를 사용하여 좌측을 200으로 우측은 나머지를 사용하도록 분할한다.


컨테이너를 사용하지 않고도 화면을 미리 분할 해놓고 가상의 선을 기준으로 좌표를 지정할 수 있게 되는 것이다.

상단 전체, 하단 전체, 좌측 전체, 우측 전체, 1,2,3,4 로 나눠진 부분공간 모두를 사용해서 원하는 곳에 아이템들을 배치 할 수 있게 된다.
또한 어플리케이션이 absolute 이므로 고정좌표를 사용해서 특정 위치에 특정 아이템을 배치 하는 것도 물론 가능하다.

분할된 가상공간의 좌표를 지정할때는 id:좌표 형식으로 지정하게 된다.
제한 좌표를 사용할때는 top, left, right, bottom 속성으로 레이아웃의 크기를 설정 해주는것이 사용하기 편하다.

예를 들어 3번 위치에 가득차게 데이터 그리드를 배치하고 오른쪽 공간과 5px 정도 떨어져서 간격을 유지 하게 하고싶다면.

<mx:DataGrid  top="content:5" left="list:5" bottom="content:5" right="list:5">

이렇게 설정한다. 상대좌표를 잡을 constraintRow나 column의 아이디를 쓰고 거기서 얼마나 떨어져야 할지를 입력한다.
위 아래는 Row를 참조하고 좌우는 Column을 참조 해서 좌표를 잡게 된다.
저런 좌표를 디자인 뷰에서 직접 입력하기는 힘들지만 완성된 레이아웃은 디자인 뷰에서도 정상적으로 보이게 되니 처음 레이아웃을 잡을때 큰 틀을 설정해놓고 내부 아이템을 세팅해 내가는 형식으로 구성하면 된다.

이 방식으로 만들게 되면 단순 레이아웃을 위한 컨테이너의 중첩을 사용하지 않아도 되기 때문에 코드를 보기에도 깔끔해지고 중첩으로 인한 부담되는 이벤트 버블링도 방지 할 수 있다.

레이아웃만을 위해서 중첩된 컨테이너를 사용하는 것은 지양하자.