flutter/순한맛(기초)

[flutter] 21강 | Column, Row 위젯

lgvv 2021. 8. 16. 12:07

✅ 이번 시간에는 Column 위젯과 Row 위젯에 대해서 알아볼 예정이야

쉬우니까 쓱 보기

 

⭐️ 레이아웃을 학습이나 급할 때, 테스트 하지 않고 이렇게 되는걸 확인할 수 있는 좋은 사이트가 있다.

https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e

 

Flutter Layout Cheat Sheet

Do you need simple layout samples for Flutter? I present you my set of Flutter layout code snippets. I will keep it short, sweet and simple…

medium.com

 

✅ Columns 위젯은 세로축의 가능한 모든 길이를 갖고 가로축의 길이만 제한된다.

import 'package:flutter/material.dart'; // 데스크탑, 앱 등에 고루 UI를 적용할 수 있게 해주는 구글이 제공해주는 패키

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      // 실질적으로 모든 앱을 감싸고 있다.
      title: 'Appbar', // 앱을 총칭하는 이름 -> 스마트 폰 앱에서 최근 사용한 앱 보여줄 때의 이름
      theme:
          ThemeData(primarySwatch: Colors.green // 특정색의 응용들을 기본 색상으로 지정해서 사용하겠
              ),
      home: MyPage(), // home은 앱이 실행될 때 가장먼저 보여주는 페이
    );
  }
}

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center, // 칼럼의 중앙에 위치
            children: [
              Container(
                width: 100,
                height : 100,
                color : Colors.green,
                child: Text('container 1'),
              ),
              Container(
                width: 100,
                height : 100,
                color : Colors.white,
                child: Text('container 2'),
              ),
              Container(
                width: 100,
                height : 100,
                color : Colors.red,
                child: Text('container 3'),
              ),

            ],
          ),
        ),

      ),
    );
  }
}

왼쪽 : 센터 위젯으로 감싸지 않은 경우, 가운데 : 센터 위젯만 적용, 오른쪽 : 센터 위젯과 칼럼에 mainAxisAlignment 적용 

가운데 사진은 센터를 했음에도 Column 위젯이 세로축을 다 차지해서 Center 위젯이 세로축을 우리가 원하는 방향으로 보여주지 못한다.

 

✅ 그렇다면 Column 위젯이 세로축을 다 차지하지 못하게 하려면 어떻게 해야할까?

 

mainAxisSize : MainAxisSize.min 으로 코드를 변경해준다.

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Center(
          child: Column(
            //mainAxisAlignment: MainAxisAlignment.center, // 칼럼의 중앙에 위치
            mainAxisSize: MainAxisSize.min, // 칼럼이 전체 다 차지 안하도록 만들기
            children: [
              Container(
                width: 100,
                height : 100,
                color : Colors.green,
                child: Text('container 1'),
              ),
              Container(
                width: 100,
                height : 100,
                color : Colors.white,
                child: Text('container 2'),
              ),
              Container(
                width: 100,
                height : 100,
                color : Colors.red,
                child: Text('container 3'),
              ),

            ],
          ),
        ),

      ),
    );
  }
}

칼럼 사이즈 조절

 

✅ 이번에는 verticalDirection를 이용하여 아래부터 정렬되도록 만들어보자

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          verticalDirection: VerticalDirection.up, // 아래부터 정렬
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),
          ],
        ),
      ),
    );
  }
}

아래부터 정렬

 

✅  다른 속성에 대해 더 알아보자

mainAxisAlignment

 - MainAxisAlignment.spaceEvenly : 칼럼에서 같은 간격만큼 띄워서 ( 처음이랑 끝 공간도 포함 )

 - MainAxisAlignment.spaceBetween : 공간만 칼럼에서 나눠서 ( 처음이랑 끝 공간은 제외 )

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          //verticalDirection: VerticalDirection.up, // 아래부터 정렬
          //mainAxisAlignment : MainAxisAlignment.spaceEvenly, // 칼럼에서 같은 간격만큼 띄워서
          mainAxisAlignment: MainAxisAlignment.spaceBetween , // 공간만 칼럼에서 나눠서
         
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),
          ],
        ),
      ),
    );
  }
}

 

좌 spaceEvenly , 우 spaceBetween

 

crossAxisAlignment

 - CrossAxisAlignment.end : 컨테이너의 끝에 맞게 정렬 

💡 플러터 에서는 width가 화면의 크기 밖으로 벗어나도 그 이상으로 커지지 않고 알아서 화면 끝 크기에 맞추게 된다.

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          //verticalDirection: VerticalDirection.up, // 아래부터 정렬
          //mainAxisAlignment : MainAxisAlignment.spaceEvenly, // 칼럼에서 같은 간격만큼 띄워서
          //mainAxisAlignment: MainAxisAlignment.spaceBetween , // 공간만 칼럼에서 나눠서
          //crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),
          ],
        ),
      ),
    );
  }
}

crossAxisAlignment.end

 

- CrossAxisAlignment.stretch : 화면의 가로축을 가능한한 최대로 늘림

🔸 width는 무시된다. 즉, 적용 안돼 

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          //verticalDirection: VerticalDirection.up, // 아래부터 정렬
          //mainAxisAlignment : MainAxisAlignment.spaceEvenly, // 칼럼에서 같은 간격만큼 띄워서
          //mainAxisAlignment: MainAxisAlignment.spaceBetween , // 공간만 칼럼에서 나눠서
          //crossAxisAlignment: CrossAxisAlignment.end, // 칼럼의 끝에 맞춤
          crossAxisAlignment: CrossAxisAlignment.stretch, // 칼럼의 가로축을 최대로 - 대신 width 적용안돼
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),

          ],
        ),
      ),
    );
  }
}

 

CrossAxisAlignment.stretch

 

✅ invisible Container 활용하기

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          //verticalDirection: VerticalDirection.up, // 아래부터 정렬
          //mainAxisAlignment : MainAxisAlignment.spaceEvenly, // 칼럼에서 같은 간격만큼 띄워서
          //mainAxisAlignment: MainAxisAlignment.spaceBetween , // 공간만 칼럼에서 나눠서
          //crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),
            Container( // invisible Container
              width: double.infinity, // 갈 수 있는데까지 가로축으로 확장하라
              height: 20,
            )
          ],
        ),
      ),
    );
  }
}

invisible container 를 통하여 컨테이너를 끝까지 확장할 수 있다.

❗️근데 이 개념이 조금 생소해서 추상적으로 이해하면 더 쉽게 받아들일 수 있다.

 

 

invisible Container 사용

 

✅ SizedBox 를 이용해서 간격 주기

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: Column(
          //mainAxisAlignment: MainAxisAlignment.center, // 가운데 정렬
          //mainAxisSize: MainAxisSize.min, // 칼럼 사이즈 컨테이너 사이즈 만큼
          //verticalDirection: VerticalDirection.up, // 아래부터 정렬
          //mainAxisAlignment : MainAxisAlignment.spaceEvenly, // 칼럼에서 같은 간격만큼 띄워서
          //mainAxisAlignment: MainAxisAlignment.spaceBetween , // 공간만 칼럼에서 나눠서
          //crossAxisAlignment: CrossAxisAlignment.end, // 칼럼의 끝에 맞춤
          crossAxisAlignment: CrossAxisAlignment.stretch, // 칼럼의 가로축을 최대로 - 대신 width 적용안돼
          children: [
            Container(
              width: 100,
              height: 100,
              color: Colors.green,
              child: Text('container 1'),
            ),
            SizedBox(
              height: 30,
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.white,
              child: Text('container 2'),
            ),
            Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: Text('container 3'),
            ),

          ],
        ),
      ),
    );
  }
}

SizedBox

Row에서는 height -> width로 바꾼다.

 

✅ Row는 Column 과 반대이므로 위의 설명을 보고 반대로 적용한다.