본문 바로가기
Flutter/Flutter Study

[Flutter] 배치 위젯 - Row, Column, Flexible 위젯, Expanded 위젯, Stack 위젯

by 왁왁s 2023. 2. 5.

목차

     

    배치 위젯(Arrange Widget)

    배치 위젯은 하위 위젯을 가로나 세로로 배치하거나 위젯들 간의 위나 아래로 겹칠 때 사용한다.

     

     

    Row 위젯

    Row 위젯은 하위 위젯을 가로로 배치하는 데 사용한다. 

     

    Row와 Coulmn에는 주축(Main Axis) 반대축(Cross Axis)라는 개념이 존재하는데, 

    Row는 가로가 주축, 세로가 반대축이 된다.

    Column의 경우엔 가로가 반대축, 세로가 주축이 된다.


     

    Row 위젯으로 작성한 전체 코드

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: SizedBox(
              height: double.infinity,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                    height: 75.0,
                    width: 75.0,
                    color: Colors.red,
                  ),
                  const SizedBox(width: 12.0),
                  Container(
                    height: 75.0,
                    width: 75.0,
                    color: Colors.green,
                  ),
                  const SizedBox(width: 12.0),
                  Container(
                    height: 75.0,
                    width: 75.0,
                    color: Colors.yellow,
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }

     

    위의 코드에서 해당 부분은 여백을 넣기 위해 들어간다. Container 사이에 여백을 두어 구분하기 쉽게 만들었다.

    const SizedBox(width: 12.0),

    해당 코드에서 주축과 반대축의 정렬을 지정할 수 있다.

    mainAxisAlignment: MainAxisAlignment.start,
    crossAxisAlignment: CrossAxisAlignment.center,

     

    위의 코드 값에서 아래의 옵션을 설정할 수 있다. 

    옵션별 사진을 아래에서 살펴보자.

    옵션 설명
    MainAxisAlignment.start 시작에 정렬
    MainAxisAlignment.center 중앙에 정렬
    MainAxisAlignment.end 끝에 정렬
    MainAxisAlignment.spaceBetween 위젯 간의 간격을 균등하게 정렬
    MainAxisAlignment.spaceAround 위젯의 간격을 균등하게 하고, 왼쪽 끝과 오른쪽 끝을 위젯 사이거리의 반만큼 배정해 정렬
    MainAxisAlignment.spaceEvenly 위젯의 간격을 균등하게 배치하고 왼쪽 끝 간격과 오른쪽 끝 간격 또한 균등하게 배치
    CrossAxisAlignment.start 시작에 정렬
    CrossAxisAlignment.center 중앙에 정렬
    CrossAxisAlignment.end 끝에 정렬
    CrossAxisAlignment.stretch 반대축을 최대한 늘려서 정렬

     

     

    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,

    위의 코드에서 center 부분을 수정하고

    start, center, end를 조합을 해 배치를 할 수 있다.

     

    start + center / center + center / end + center

     


    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    crossAxisAlignment: CrossAxisAlignment.center,

    아래의 옵션은 가로(주축)에만 사용이 가능하다.

    MainAxisAlignment. 부분에 옵션 값을 넣어주면 된다.

    spaceBetween / spaceAround / spaceEvenly

     


    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    crossAxisAlignment: CrossAxisAlignment.stretch,

     


     

     

    Column 위젯

    Column 위젯은 Row 위젯과 같은 매개변수를 사용하지만, 주축과 반대축이 반대로 있다.

     

    child: Row라고 되어 있던 부분을 Column으로 바꾸면 Column 위젯을 사용할 수 있다.

    child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      crossAxisAlignment: CrossAxisAlignment.stretch,
    )

     

    또한 width: double.infinity 설정을 해주어야 화면의 가로를 모두 사용할 수 있으므로 설정을 해줘야 한다.

    width: double.infinity,
    height: double.infinity,

     

    옵션 설명
    MainAxisAlignment.start 시작에 정렬
    MainAxisAlignment.center 중앙에 정렬
    MainAxisAlignment.end 끝에 정렬
    MainAxisAlignment.spaceBetween 위젯 간의 간격을 균등하게 정렬
    MainAxisAlignment.spaceAround 위젯의 간격을 균등하게 하고, 왼쪽 끝과 오른쪽 끝을 위젯 사이거리의 반만큼 배정해 정렬
    MainAxisAlignment.spaceEvenly 위젯의 간격을 균등하게 배치하고 왼쪽 끝 간격과 오른쪽 끝 간격 또한 균등하게 배치
    CrossAxisAlignment.start 시작에 정렬
    CrossAxisAlignment.center 중앙에 정렬
    CrossAxisAlignment.end 끝에 정렬
    CrossAxisAlignment.stretch 반대축을 최대한 늘려서 정렬

     

    아래의 코드 부분을 위의 표를 참고해 작성해보자.

    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,

     

    위의 코드에서 center 부분을 수정하고

    start, center, end를 조합을 해 배치를 할 수 있다.

     

    start + center / center + center / end + center

     

     

    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    crossAxisAlignment: CrossAxisAlignment.center,​

     

    아래의 옵션은 세로(반대축)에만 사용이 가능하다.

    spaceBetween / spaceAround / spaceEvenly

     

     

    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.stretch,

     


     

    Flexible 위젯

    Flexible 위젯은 Row 위젯과 Column 위젯에 함께 사용하는 위젯으로, child가 Row와 Column에서의 여유 공간을 활용할 수 있다.

     

    위에서 말한 바와 같이 Flexible 위젯은 Row와 Column 안에서 사용해야 한다.

     

    여유 공간을 얼마나 차지할 지 child 별로 비율을 지정할 수 있다.

     

     

     

     

    Column 1:3:1 / Row 1:3:1

     

     

     

    또한 Flex는 Expanded와 함께 사용될 수 있으며 비율을 지정할 수 있다.

     

    flexible을 사용하면 다른 위젯들과 비율을 차지 한 다음에, 해당 위젯의 크기만큼만 차지하고 남는 공간은 사용하지 않고 버린다. flexible은 잘 사용하지 않는다.

                Expanded(
                    flex: 1,
                    child: Container(
                      color: Colors.red,
                      width: 50,
                      height: 50,
                    ),
                  ),
                  Expanded(
                    flex: 2,
                    child: Container(
                      color: Colors.blue,
                      width: 50,
                      height: 50,
                    ),
                  ),

     

     

     


     

     

    FlextFit.tight

    강제적으로 사용할 수 있는 만큼 최대한 늘리기

     

    children: [
                  Container(
                    width: 50,
                    height: 100,
                    color: Colors.red,
                  ),
                  Flexible(
                    fit: FlexFit.tight,
                    child: Container(
                      height: 100,
                      color: Colors.green,
                    ),
                  ),
                  Container(
                    width: 150,
                    height: 100,
                    color: Colors.yellow,
                  ),
                ],

     


     

    FlextFit.loose

    차지해야할 공간 만큼만, 필요한 공간만 차지하기

     

                children: [
                  Container(
                    width: 50,
                    height: 100,
                    color: Colors.red,
                  ),
                  Flexible(
                    fit: FlexFit.loose,
                    child: Container(
                        height: 100,
                        color: Colors.green,
                        child: Text('필요한 사이즈에 맞게 줄어듭니다')),
                  ),
                  Container(
                    width: 50,
                    height: 100,
                    color: Colors.yellow,
                  ),
                ],

     


     

    Expanded 위젯

    Expanded 위젯은 Flexible 위젯을 상속하는 위젯으로, Row와 Column 위젯과 함께 쓰이며 해당 위제세에서 남는 여유 공간을 최대한 차지한다.

     

    위에서 말한 바와 같이 Expanded 위젯은 Row와 Column 안에서 사용해야 한다.

     

    Flexible과 동알하게 남는 공간에 대한 비중을 설정할 수 있으나, Row와 Column의 Child가 화면을 가득 채우도록 한다는 점이 다르다. 

     

     

     

     

              child: Column(
                children: [
                  Expanded(
                      child: Container(
                    color: Colors.red,
                  )),
                  Expanded(
                      child: Container(
                    color: Colors.green,
                  )),
                  Expanded(
                      child: Container(
                    color: Colors.yellow,
                  )),
                ],
              ),

     


     

    Stack 위젯

    Stack 위젯은 위젯들을 여러 개 서로 겹치게 배치할 때 사용하는 기능이다.

    Stack 위젯을 사용하면 위젯 위에 올라간 듯한 효과를 줄 수 있다.

     

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: SafeArea(
              child: Stack(
                children: [
                  Container(
                    width: 400,
                    height: 400,
                    color: Colors.pinkAccent,
                  ),
                  Container(
                    width: 350,
                    height: 350,
                    color: Colors.purple,
                  ),
                  Container(
                    width: 300,
                    height: 300,
                    color: Colors.blue,
                  ),
                  Container(
                    width: 250,
                    height: 250,
                    color: Colors.green,
                  ),
                  Container(
                    width: 200,
                    height: 200,
                    color: Colors.yellow,
                  ),
                  Container(
                    width: 150,
                    height: 150,
                    color: Colors.orange,
                  ),
                  Container(
                    width: 100,
                    height: 100,
                    color: Colors.red,
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }

     

     


     

    배치 위젯 연습하기 (ex 사람 얼굴 만들기)

     

    import 'package:flutter/material.dart';
    
    class HomeScreen extends StatelessWidget {
      const HomeScreen({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            bottom: false,
            child: Container(
              width: MediaQuery.of(context).size.width,
              color: Colors.black,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Expanded(
                        child: Container(
                          width: 50,
                          height: 50,
                          color: Colors.red,
                        ),
                      ),
                      Expanded(
                        child: Container(
                          width: 50,
                          height: 50,
                          color: Colors.blue,
                        ),
                      ),
                      Expanded(
                        child: Container(
                          width: 50,
                          height: 50,
                          color: Colors.amber,
                        ),
                      ),
                      Expanded(
                        child: Container(
                          width: 50,
                          height: 50,
                          color: Colors.green,
                        ),
                      ),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.white,
                      ),
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.white,
                      ),
                    ],
                  ),
                  Column(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.red,
                      ),
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.blue,
                      ),
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.amber,
                      ),
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.green,
                      ),
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      Container(
                        width: 50,
                        height: 50,
                        color: Colors.purple,
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }

    댓글