본문 바로가기
Flutter for Beginners

Flutter의 배치(Layout) 관련 위젯

by Andrew's Akashic Records 2025. 3. 14.
728x90

Flutter

Flutter의 배치(Layout) 관련 위젯

Flutter에서 UI를 구성할 때 배치(Layout) 관련 위젯을 사용하여 요소들을 정렬하고 배치할 수 있습니다.
배치 관련 위젯은 크게 단일 요소 배치, 수직/수평 정렬, 겹쳐 배치, 그리드 배치 등으로 나눌 수 있습니다.

1. Container (기본 배치 및 스타일링)

Container는 크기, 패딩, 마진, 정렬, 색상 등을 설정할 수 있는 가장 기본적인 배치 위젯입니다.

예제: 크기, 정렬, 색상 적용

Container(
  width: 200,
  height: 100,
  alignment: Alignment.center, // 내부 콘텐츠 정렬
  decoration: BoxDecoration(
    color: Colors.blue, // 배경색
    borderRadius: BorderRadius.circular(10), // 모서리 둥글게
  ),
  child: Text("Hello Flutter", style: TextStyle(color: Colors.white)),
)
  • Container는 텍스트, 이미지, 버튼 등을 감싸서 스타일을 적용할 때 유용합니다.

2. Row (가로 정렬)

Row 위젯을 사용하면 여러 개의 위젯을 가로로 배치할 수 있습니다.

예제: Row를 이용한 가로 배치

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 가로 정렬
  children: [
    Icon(Icons.star, color: Colors.red, size: 40),
    Icon(Icons.star, color: Colors.green, size: 40),
    Icon(Icons.star, color: Colors.blue, size: 40),
  ],
)
  • Row는 네비게이션 바, 아이콘 정렬, 버튼 그룹 등에 많이 사용됩니다.

2.1. mainAxisAlignment 정렬 옵션

옵션 설명
start 왼쪽 정렬 (기본값)
center 가운데 정렬
end 오른쪽 정렬
spaceBetween 양쪽 끝을 맞추고 요소 사이 간격 균등 배치
spaceAround 요소들 간의 간격이 동일 (양쪽 끝은 절반 간격)
spaceEvenly 요소들과 양쪽 끝의 간격이 동일

3. Column (세로 정렬)

Column을 사용하면 위젯들을 세로로 배치할 수 있습니다.

예제: Column을 이용한 세로 배치

Column(
  mainAxisAlignment: MainAxisAlignment.center, // 세로 정렬
  crossAxisAlignment: CrossAxisAlignment.center, // 가로 정렬
  children: [
    Text("첫 번째 줄"),
    SizedBox(height: 10), // 간격 추가
    Text("두 번째 줄"),
    SizedBox(height: 10),
    Text("세 번째 줄"),
  ],
)
  • Column은 리스트 형식의 UI, 설정 화면, 폼 입력 필드 정렬 등에 사용됩니다.

3.1. crossAxisAlignment 정렬 옵션

옵션 설명
start 왼쪽 정렬 (기본값)
center 가운데 정렬
end 오른쪽 정렬
stretch 가능한 최대 크기로 확장

4. Stack (위젯 겹치기)

Stack은 위젯을 서로 겹쳐서 배치할 때 사용됩니다.

예제: Stack을 이용한 겹쳐진 UI

Stack(
  children: [
    Container(width: 200, height: 200, color: Colors.blue), // 바탕 박스
    Positioned(
      top: 50,
      left: 50,
      child: Icon(Icons.star, color: Colors.white, size: 50),
    ),
  ],
)
  • Stack은 이미지 위에 텍스트를 겹쳐 놓거나, 배지를 표시할 때 유용합니다.

4.1. Positioned 위젯을 사용하여 위치 지정 가능

속성 설명
top 위에서부터 거리 지정
bottom 아래에서부터 거리 지정
left 왼쪽에서부터 거리 지정
right 오른쪽에서부터 거리 지정

5. Expanded (Row/Column 내부에서 비율 조정)

Expanded는 Row 또는 Column 내부에서 특정 위젯이 가능한 공간을 최대로 차지하도록 함.

예제: Expanded를 사용한 비율 조정

Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(height: 100, color: Colors.red),
    ),
    Expanded(
      flex: 1,
      child: Container(height: 100, color: Colors.green),
    ),
  ],
)
  • Expanded를 사용하면 레이아웃을 반응형으로 조정 가능합니다.

5.1. flex 속성

  • flex: 2 → 전체 공간의 2배 차지
  • flex: 1 → 전체 공간의 1배 차지

6. Wrap (자동 줄바꿈)

Wrap은 Row 또는 Column이 넘칠 때 자동으로 다음 줄로 넘어가게 배치합니다.

예제: 자동 줄 바꿈 UI

Wrap(
  spacing: 10, // 아이템 간격
  runSpacing: 10, // 줄 간격
  children: List.generate(10, (index) {
    return Container(
      padding: EdgeInsets.all(10),
      color: Colors.blue,
      child: Text("Item $index", style: TextStyle(color: Colors.white)),
    );
  }),
)
  • Wrap은 태그 UI, 버튼 그룹, 반응형 레이아웃 등에 유용합니다.

7. GridView (그리드 형태 배치)

GridView는 격자(그리드) 형식으로 위젯을 배치하는 데 사용됩니다.

예제: GridView.count를 이용한 그리드 레이아웃

GridView.count(
  crossAxisCount: 2, // 한 줄에 2개의 아이템 표시
  crossAxisSpacing: 10, // 가로 간격
  mainAxisSpacing: 10, // 세로 간격
  children: List.generate(6, (index) {
    return Container(
      color: Colors.blue,
      child: Center(child: Text("Item $index", style: TextStyle(color: Colors.white))),
    );
  }),
)
  • GridView는 갤러리, 상품 리스트, 이미지 정렬 등에 자주 사용됩니다.

배치 관련 위젯 정리

위젯 기능
Container 크기, 정렬, 배경색 설정 가능
Row 가로 방향으로 위젯 배치
Column 세로 방향으로 위젯 배치
Stack 위젯을 겹쳐서 배치
Expanded Row 또는 Column 내부에서 공간을 최대로 차지
Wrap 가로/세로로 넘칠 경우 자동 줄바꿈
GridView 그리드 형식으로 정렬

Flutter의 배치(Layout) 관련 위젯 예제 코드

Flutter의 레이아웃 관련 위젯을 활용하면 UI 요소를 정렬하고 배치할 수 있습니다.
이번 예제에서는 Column, Row, Stack, Expanded, Wrap, GridView 등의 주요 레이아웃 위젯을 사용하여 다양한 배치 방식을 다뤄보겠습니다.

예제 코드 (main.dart)

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: LayoutExampleScreen(),
    );
  }
}

class LayoutExampleScreen extends StatelessWidget {
  const LayoutExampleScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("배치 관련 위젯 예제")),
      body: SingleChildScrollView(
        child: Column(
          children: [
            _buildRowExample(),
            _buildColumnExample(),
            _buildStackExample(),
            _buildExpandedExample(),
            _buildWrapExample(),
            _buildGridExample(),
          ],
        ),
      ),
    );
  }

  // 1. Row (가로 정렬)
  Widget _buildRowExample() {
    return Container(
      margin: EdgeInsets.all(10),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Icon(Icons.star, color: Colors.red, size: 40),
          Icon(Icons.star, color: Colors.green, size: 40),
          Icon(Icons.star, color: Colors.blue, size: 40),
        ],
      ),
    );
  }

  // 2. Column (세로 정렬)
  Widget _buildColumnExample() {
    return Container(
      margin: EdgeInsets.all(10),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text("첫 번째 줄"),
          SizedBox(height: 10),
          Text("두 번째 줄"),
          SizedBox(height: 10),
          Text("세 번째 줄"),
        ],
      ),
    );
  }

  // 3. Stack (겹쳐진 UI)
  Widget _buildStackExample() {
    return Container(
      margin: EdgeInsets.all(10),
      width: 150,
      height: 150,
      child: Stack(
        alignment: Alignment.center,
        children: [
          Container(width: 150, height: 150, color: Colors.blue),
          Positioned(top: 10, left: 10, child: Icon(Icons.star, color: Colors.white, size: 40)),
          Positioned(bottom: 10, right: 10, child: Icon(Icons.favorite, color: Colors.red, size: 40)),
        ],
      ),
    );
  }

  // 4. Expanded (비율 기반 레이아웃)
  Widget _buildExpandedExample() {
    return Container(
      margin: EdgeInsets.all(10),
      height: 100,
      child: Row(
        children: [
          Expanded(
            flex: 2,
            child: Container(color: Colors.red),
          ),
          Expanded(
            flex: 1,
            child: Container(color: Colors.green),
          ),
        ],
      ),
    );
  }

  // 5. Wrap (자동 줄 바꿈 레이아웃)
  Widget _buildWrapExample() {
    return Container(
      margin: EdgeInsets.all(10),
      child: Wrap(
        spacing: 10, // 가로 간격
        runSpacing: 10, // 세로 간격
        children: List.generate(10, (index) {
          return Container(
            padding: EdgeInsets.all(10),
            color: Colors.blue,
            child: Text("Item $index", style: TextStyle(color: Colors.white)),
          );
        }),
      ),
    );
  }

  // 6. GridView (그리드 배치)
  Widget _buildGridExample() {
    return Container(
      margin: EdgeInsets.all(10),
      height: 200,
      child: GridView.count(
        crossAxisCount: 3, // 한 줄에 3개씩 배치
        crossAxisSpacing: 10,
        mainAxisSpacing: 10,
        children: List.generate(6, (index) {
          return Container(
            color: Colors.orange,
            child: Center(child: Text("Grid $index", style: TextStyle(color: Colors.white))),
          );
        }),
      ),
    );
  }
}

 

예제 실행 화면

 

728x90