[Flutter] 기본 위젯 알아보기

이 글은 [Must Have] 코드팩토리의 플러터 프로그래밍 2판에서 발췌했습니다.
골든래빗 출판사
코드팩토리(최지호) 지음

플러터는 화면에 그려지는 모든 요소가 위젯으로 구성되어 있습니다. 플러터 프레임워크는 수십 가지 기본 위젯을 제공하며 앱 개발자가 직접 위젯을 만들 수도 있습니다. 이 모든 위젯을 다 알아볼 수는 없으니 자주 사용하는 위젯을 텍스트, 제스처, 디자인, 배치 관련 위젯으로 분류해 알아보겠습니다.

 

[Flutter] 기본 위젯 알아보기

 

1. 위젯 소개

‘Everything is a Widget’은 구글에서 플러터에서 소개하는 문구입니다. 한국어로 직역하면 ‘모든 것은 위젯이다’입니다. 플러터에서 화면에 보여지는 UI와 관련된 모든 요소는 위젯으로 구성되어 있습니다. 위젯은 현재 주어진 상태state(데이터)를 기반으로 어떤 UI를 구현할지를 정의합니다. 위젯의 상태가 변경되면 변경 사항에 알맞게 변경된 UI를 화면에 다시 그려줍니다. 이때 플러터 프레임워크는 기존 상태의 위젯과 새로운 상태의 위젯을 비교해서 UI 변화를 반영할 때 필요한 최소한의 변경 사항을 산출해서 화면을 그려냅니다. 결과적으로 플러터는 최소한의 리소스를 이용해서 UI 변경을 이끌어낼 수 있으며, 쉽게 최대 120FPS까지 높은 퍼포먼스를 발휘할 수 있습니다.

위젯은 자식을 하나만 갖는 위젯과 자식을 여럿 갖는 위젯으로 나뉩니다. 자식을 하나만 갖는 대표적인 위젯들은 다음과 같으며 대체로 child 매개변수를 입력받습니다.

  • Container 위젯 : 자식을 담는 컨테이너 역할을 합니다. 다만 단순하게 자식을 담는 역할을 하는 게 아니라 배경색, 너비와 높이, 테두리 등의 디자인을 지정할 수 있습니다.
  • GestureDetector 위젯 : 플러터에서 제공하는 제스처 기능을 자식 위젯에서 인식하는 위젯입니다. 탭이나 드래그 그리고 더블 클릭 같은 제스처 기능이 자식 위젯에 인식됐을 때 함수를 실행할 수 있습니다.
  • SizedBox 위젯 : 높이와 너비를 지정하는 위젯입니다. Container 위젯과 다르게 디자인적 요소는 적용할 수 없고 const 생성자로 선언할 수 있어서 퍼포먼스 측면에서 더 효율적입니다.

다수의 자식을 입력할 수 있는 위젯은 children 매개변수를 입력받으며 리스트로 여러 위젯을 입력할 수 있습니다. 대표적인 다수의 자식을 입력할 수 있는 위젯은 아래와 같습니다.

  • Column 위젯 : children 매개변수에 입력된 모든 위젯들을 세로로 배치합니다.
  • Row 위젯 : children 매개변수에 입력된 모든 위젯들을 가로로 배치합니다.
  • ListView 위젯 : 리스트를 구현할 때 사용합니다. 마찬가지로 children 매개변수에 다수의 위젯을 입력할 수 있으며 입력된 위젯이 화면을 벗어나게 되면 스크롤이 가능해집니다.

child와 children 매개변수에 지속적으로 하위 위젯을 입력하면 크리스마스 트리처럼 위젯 계층이 정리됩니다. 예를 들어 다음과 같은 UI를 구현한다고 가정하겠습니다.

 

 

위 UI의 위젯 트리는 다음과 같습니다. 이렇게 UI를 위젯 트리로 그릴 수 있어야 플러터 앱 프로그래밍을 할 수 있으니 두 그림 간의 관계를 꼭 이해하고 넘어가주세요.

 

 

이외에도 플러터에서 기본으로 제공하는 위젯들은 플러터 공식 웹사이트에서 API를 확인할 수 있습니다.

1.1 Children와 Child의 차이점

플러터는 위젯 아래에 계속 위젯이 입력되는 형태로 ‘위젯 트리’를 구성하여 UI를 제작합니다. child 매개변수와 children 매개변수는 위젯에 하위 위젯을 추가할 때 사용합니다. 명칭에서도 알 수 있듯이 child는 위젯을 하나만 추가할 수 있고 children은 여럿을 추가할 수 있습니다. 대부분 위젯은 child 또는 children 매개변수를 하나만 제공합니다. child와 children 매개변수를 동시에 입력받는 위젯은 존재하지 않습니다. 다음 예제에서 child와 children 매개변수의 차이를 알아보겠습니다.

 

import 'package:flutter/material.dart';

void main() {
 runApp(
   MaterialApp(
     home: Scaffold(
       body: Center(

         // ❶ 하나의 위젯만 가운데 정렬 가능
         child: Text('Code Factory'),
       ),
     ),
   ),
 );
}

 

▼ 실행 결과

 

❶ child 매개변수에는 단 하나의 위젯만 입력할 수 있습니다. Center 위젯은 child 매개변수에 입력된 위젯을 가운데 정렬해주는 기능을 갖고 있기 때문에 Text 위젯을 가운데 정렬해줍니다.

반면 children 매개변수는 여러 위젯을 리스트에 입력할 수 있습니다. 리스트에 입력된 순서대로 화면에 그려집니다. 위젯을 세로로 배치할 수 있는 위젯인 Column 위젯을 사용해서 children 매개변수를 알아보겠습니다.

import 'package:flutter/material.dart';

void main() {
 runApp(
   MaterialApp(
     debugShowCheckedModeBanner: false,
     home: Scaffold(
       body: SizedBox(
         width: double.infinity,
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           // ❶ 여러 위젯을 Column 위젯에 입력 가능
           children: [
             Text('Code'),
             Text('Factory'),
           ],
         ),
       ),
     ),
   ),
 );
}

 

▼ 실행 결과

 

❶ children 매개변수는 리스트를 입력받고 리스트 안에는 원하는 만큼 위젯을 입력할 수 있습니다. ‘Code’라는 글자를 입력한 Text 위젯이 먼저 입력됐고 이어서 ‘Factory’라는 글자가 입력된 Text 위젯이 입력됐으니 2행에 걸쳐 ‘Code Factory’라는 글자가 화면에 그려집니다.

 

2. 위젯 실습용 템플릿 작성

이제부터는 안드로이드 스튜디오에서 필수 위젯들을 하나씩 학습합니다.

 

Todo

01 실습을 하려면 프로젝트를 생성해야 하니 5.2.1 ‘안드로이드 스튜디오에서 프로젝트 생성하기’를 참고해서 프로젝트를 새로 생성해주세요.

02 앞으로 배울 위젯들을 화면에 구현하려면 배우려는 위젯 코드 외에 기본 코드가 약간 필요합니다. 다음 템플릿을 참고해서 기본 코드를 구현한 후 ❶ child 매개변수에 실습 예제들을 작성해가며 공부하겠습니다.

 

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       body: Center(
         child: // ❶ 여기에 예제 코드 작성하기
       ),
     ),
   );
 }
}

 

3. 텍스트 관련 위젯

화면에 글자를 보여주려면 글자를 렌더링할 수 있는 위젯을 사용해야 합니다. 이 책에서는 가장 대표적인 텍스트 관련 위젯인 Text 위젯만 다룹니다.

 

💡Note: 플러터는 RichText 위젯과 Paragraph 같은 클래스도 제공합니다.

 

💡Note: 예제를 실행하면 use key in widget constructors(위젯 생성자에 키값을 포함하라)와 prefer const with constant constructors(const 생성자를 사용할 수 있으면 const 생성자를 사용하라) 워닝이 보일 수 있습니다. 워닝은 프로그램을 실행하는 데 문제는 없지만 변경해주면 성능이 향상되거나 코드 관리에 유리할 수 있는 사항입니다. 연습 예제이니 워닝을 무시하고 코드를 실습하겠습니다.

 

Text 위젯은 글자를 적고 스타일링하는 위젯입니다. 첫 번째 포지셔널 파라미터에 원하는 문자열을 작성하고 style이라는 네임드 파라미터를 사용해 스타일을 지정합니다.

 

▼ Text 위젯 예제 코드

Text(
// 작성하고 싶은 글
'코드팩토리',
// 글자에 스타일 적용
 style: TextStyle(
 // 글자 크기
 fontSize: 16.0,
 // 글자 굵기
 fontWeight: FontWeight.w700,
 // 글자 색상
 color: Colors.blue,
 ),
),

 

▼ 실행 결과

4. 제스처 관련 위젯

사용자가 키보드로 글자를 입력하는 행위 외의 모든 입력을 플러터에서는 제스처라고 부릅니다. 예를 들어 화면을 한 번 탭한다거나, 두 번 탭한다거나, 길게 누르는 행동 모두가 제스처입니다. GestureDetector 위젯(6.4.3)은 모든 제스처를 매개변수로 제공해줍니다. 제스처 관련 위젯은 하위 위젯에 탭이나 드래그처럼 특정 제스처가 입력됐을 때 인지하고 콜백 함수를 실행합니다. Button, IconButton, GestureDetector, FloatingActionButton 위젯을 순서대로 알아보겠습니다.

 

4.1 Button 위젯

플러터 머티리얼 패키지에서 기본 제공하는 버튼으로 TextButton, OutlinedButton, Elevated Button이 있습니다. TextButton, OutlinedButton, ElevatedButton 모두 버튼을 누르면 색이 변경되는 리플 효과를 지원합니다.

 

 

각각을 구현하는 코드를 살펴보겠습니다.

 

▼ TextButton 코드

TextButton(
// 클릭 시 실행
onPressed: () {},
// 스타일 지정
style: TextButton.styleFrom(
 // 주 색상 지정
 foregroundColor: Colors.red,
 ),
 // 버튼에 넣을 위젯
 child: Text('텍스트 버튼'),
),

 

▼ 실행 결과

▼ OutlinedButton 예제

OutlinedButton(
 // 클릭 시 실행할 함수
 onPressed: () {},
 // 버튼 스타일
 style: OutlinedButton.styleFrom(
   foregroundColor: Colors.red,
 ),
 // 버튼에 들어갈 위젯
 child: Text('아웃라인드 버튼'),
),

 

▼ 실행 결과

 

▼ ElevatedButton 예제

ElevatedButton(
 // 클릭 시 실행할 함수
 onPressed: (){},
 // 버튼 스타일링
 style: ElevatedButton.styleFrom(
   backgroundColor: Colors.red,
 ),
 // 버튼에 들어갈 위젯
 child: Text('엘레베이티드 버튼'),
),

 

▼ 실행 결과

 

4.2 IconButton 위젯

IconButton은 아이콘을 버튼으로 생성하는 위젯입니다. icon 매개변수에 보여주고 싶은 아이콘을 넣을 수 있습니다. onPressed 매개변수에 IconButton을 누르면 실행할 콜백 함수를 제공할 수 있습니다. 아이콘은 글리프(Glyph) 기반의 아이콘을 사용할 수 있으며 ❶ Icons 클래스를 통해 플러터에서 제공하는 기본 아이콘들을 사용할 수 있습니다.

 

▼ IconButton 예제

IconButton(
 onPressed: () {},
 icon: Icon(
   // ❶ 플러터에서 기본으로 제공하는 아이콘입니다.
   // 제공되는 아이콘 목록은 다음 링크에서 확인해볼 수 있습니다.
   // https://fonts.google.com/icons
   Icons.home,
 ),
)

 

4.3 GestureDetector 위젯

앱은 모든 입력을 손가락으로 합니다. 그래서 손가락으로 하는 여러 가지 입력을 인지하는 위젯이 필요한데 GestureDetector가 바로 그 역할을 합니다.

 

▼ GestureDetector 예제

GestureDetector(
 // ❶ 한 번 탭했을 때 실행할 함수
 onTap: (){
   // 출력 결과는 안드로이드 스튜디오의 [Run] 탭에서 확인 가능합니다.
   print('on tap');
 },
 // ❷ 두 번 탭했을 때 실행할 함수
 onDoubleTap: ( ){
   print('on double tap');
 },
 // ❸ 길게 눌렀을 때 실행할 함수
 onLongPress: (){
   print('on long press');
 },
 // Gesture를 적용할 위젯
 child: Container(
   decoration: BoxDecoration(
     color: Colors.red,
   ),
   width: 100.0,
   height: 100.0,
 ),
)

 

▼ 실행 결과

 

위 GestureDetector의 child 위젯에 한 번 탭, 두 번 탭, 길게 눌렀을 때의 예제 코드를 알아봤위 GestureDetector의 child 위젯에 한 번 탭, 두 번 탭, 길게 눌렀을 때의 예제 코드를 알아봤을 수 있습니다.

다음 표에 GestureDetector가 제공하는 중요한 제스처를 정리하였습니다.

▼ GestureDetector 위젯에서 제공하는 제스처 매개변수*

* https://api.flutter.dev/flutter/widgets/GestureDetector-class.html

 

4.4 FloatingActionButton 위젯

FloatingActionButton은 Material Design에서 추구하는 버튼 형태입니다. 안드로이드 앱들을 사용하다 보면 화면의 오른쪽 아래에 동그란 플로팅 작업 버튼을 쉽게 볼 수 있습니다. FloatingActionButton과 Scaffold를 같이 사용하면 특별한 어려움 없이 해당 형태의 디자인을 구현할 수 있습니다.

 

▼ FloatingActionButton 예제

import 'package:flutter/material.dart';

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

class FloatingActionButtonExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: FloatingActionButton(
          // 클릭했을 때 실행할 함수
          onPressed: () {},
          child: Text('클릭'),
        ),
        body: Container(),
      ),
    );
  }
}

 

▼ 실행 결과

 

5. 디자인 관련 위젯

디자인 관련 위젯은 배경을 추가하거나 간격을 추가하거나 패딩을 추가하는 등 디자인적 요소를 적용할 때 사용합니다.

 

5.1 Container 위젯

Container 위젯은 말 그대로 다른 위젯을 담는 데 사용됩니다. 위젯의 너비와 높이를 지정하거나, 배경이나 테두리를 추가할 때 많이 사용됩니다.

 

▼ Container 위젯

Container(
 // 스타일 작용
 decoration: BoxDecoration(
   // 배경 색깔 적용
   color: Colors.red,
   // 테두리 적용
   border: Border.all(
     // 테두리 굵기
     width: 16.0,
                // 테두리 색상
                color: Colors.black,
              ),
              // 모서리 둥글게 만들기
              borderRadius: BorderRadius.circular(
                16.0,
              ),
            ),
            // 높이
            height: 200.0,
            // 너비
            width: 100.0,
          )

 

▼ 실행 결과

 

Container 위젯은 다른 위젯처럼 child 매개변수를 사용할 수 있습니다.

 

5.2 SizedBox 위젯

SizedBox 위젯은 일반적으로 일정 크기의 공간을 공백으로 두고 싶을 때 사용됩니다. Container 위젯을 사용해도 공백을 만들 수 있지만 SizedBox는 const 생성자를 사용했을 때 퍼포먼스에서 이점을 얻을 수 있습니다.

 

▼ SizedBox 위젯

SizedBox(
 // 높이 지정
 height: 200.0,
 
 // 너비 지정
 width: 200.0,
            
 // SizedBox는 색상이 없으므로 크기를 확인하는
 // 용도로 Container 추가
 child: Container(
   color: Colors.red,
 ),
)

 

▼ 실행 결과

 

5.3 Padding 위젯

Padding 위젯은 child 위젯에 여백을 제공할 때 사용합니다. Padding 위젯을 사용하면 Padding 위젯의 상위 위젯과 하위 위젯 사이의 여백을 둘 수 있습니다. Padding 위젯의 padding 매개변수는 EdgeInsets라는 값을 입력해야 합니다. 또한 child 매개변수에 Padding을 적용하고 싶은 위젯을 입력할 수 있습니다.

 

▼ Padding 예제

Container(
 color: Colors.blue,
 child: Padding(

   // 상하, 좌우로 모두 16픽셀만큼 패딩을 적용합니다.
   padding: EdgeInsets.all(
     16.0,
   ),
   child: Container(
     color: Colors.red,
     width: 50.0,
     height: 50.0,
   ),
 ),
)

 

▼ 출력 결과

 

패딩은 적용된 위젯이 차지하는 크기 내부에서 간격이 추가됩니다. 플러터에서 자주 사용하지는 않지만 위젯의 바깥에 간격을 추가해주는 마진(Magin)이라는 기능도 있습니다. 다만 마진은 따로 위젯이 존재하지 않고 Container 위젯에 추가할 수 있습니다. 다음 예제에서 패딩 위젯과 마진 위젯이 동시에 적용된 실습을 진행해보고 둘의 차이를 이해해보겠습니다.

 

// ❸ 최상위 검정 컨테이너 (margin이 적용되는 대상)
Container(
 color: Colors.black,

 // ❷ 중간 파란 컨테이너
 child: Container(
   color: Colors.blue,

   // 마진 적용 위치
   margin: EdgeInsets.all(16.0),

   // 패딩 적용
   child: Padding(
     padding: EdgeInsets.all(16.0),
 
     // ❶ 패딩이 적용된 빨간 컨테이너
     child: Container(
       color: Colors.red,
       width: 50,
       height: 50,
     ),
   ),
 ),
)

 

▼ 출력 결과

 

EdgeInsets 클래스는 다양한 생성자를 제공합니다. 자세한 사항은 다음 표로 정리해두었으니 용도에 맞게 사용하기 바랍니다.

 

▼ EdgeInsets 클래스 생성자 종류 정리

 

5.4 SafeArea

현대 핸드폰은 크기와 디자인 모두 여러 가지입니다. 특히 애플 아이폰의 노치 디자인은 정말 특이한 디자인입니다. 플러터는 가용되는 화면을 모두 사용하기 때문에 노치가 있는 핸드폰에서 노치에 위젯들이 가릴 수 있습니다. SafeArea 위젯을 사용하면 따로 기기별로 예외 처리를 하지 않고도 안전한(Safe) 화면에서만 위젯을 그릴 수 있습니다.

 

▼ SafeArea 예제

SafeArea(
 // 원하는 부위만 따로 적용할 수도 있습니다.
 // true는 적용 false는 미적용
 top: true,
 bottom: true,
 left: true,
 right: true,
 child: Container(
   color: Colors.red,
   height: 300.0,
   width: 300.0,
 ),
),

 

▼ SafeArea 적용

 

▼ SafeArea 미적용

 

6. 배치 관련 위젯

배치 관련 위젯은 하위 위젯을 가로 또는 세로로 배치하거나 위젯 위에 위젯을 겹칠 때 사용합니다.

 

6.1 Row 위젯

Row는 Column과 함께 위젯을 가로세로로 배치하는 데 사용됩니다. Row는 말 그대로 가로로 위젯을 배치하는 데 사용됩니다. 하나의 child 위젯을 입력받는 위젯들과 다르게 여러 개의 child 위젯을 입력받을 수 있는 children 매개변수를 노출합니다. Row와 Column에는 주축(Main Axis)과 반대축(Cross Axis)이라는 개념이 존재하는데 Row는 가로가 주축, 세로가 반대축이 되고 Column의 경우 반대가 됩니다. 주축과 반대축을 어떻게 조합하냐에 따라 Row와 Column 위젯을 이용해서 다양하게 배치할 수 있습니다.

 

▼ Row 위젯의 주축과 반대축

 

▼ Column 위젯의 주축과 반대축

 

위젯을 가로로 배치하는 Row 위젯을 알아보겠습니다. Row 위젯의 crossAxisAlignment 매개변수를 테스트하려면 위젯들을 배치할 수 있는 공간을 확보해야 합니다. 그래서 지금까지 작성한 예제와 코드가 약간 다르니 다음 코드를 잘 참고해서 따라와주세요.

 

▼ Row 위젯 예제

import 'package:flutter/material.dart';

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

class RowWidgetExample 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: 50.0,
                width: 50.0,
                color: Colors.red,
              ),
              // SizedBox는 일반적으로 공백을
              // 생성할 때 사용
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.green,
              ),
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

▼ 출력 결과

 

다음 두 표에서 MainAxisAlignment와 CrossAxisAlignment를 변경했을 때 어떤 UI를 구현할 수 있는지 확인해보세요.

 

▼ MainAxisAlignment 옵션(예제는 모두 CrossAxisAlignment.center 기준)

 

▼ CrossAxisAlignment 옵션(예제는 모두 MainAxisAlignment.center 기준)

 

6.2 Column 위젯

Column 위젯은 Row 위젯과 완전히 같은 매개변수들을 노출합니다. 다만 Row에서 이미 설명한 것처럼 주축과 반대축이 Row와 반대로 이루어져 있습니다.

 

▼ Column 위젯

import 'package:flutter/material.dart';

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

class ColumnWidgetExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SizedBox(
          width: double.infinity,
          child: Column(
            // 주축 정렬 지정
            mainAxisAlignment: MainAxisAlignment.start,
            // 반대축 정렬 지정
            crossAxisAlignment: CrossAxisAlignment.start,
            // 넣고 싶은 위젯 입력
            children: [
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.red,
              ),
              // SizedBox는 일반적으로 공백을 생성할 때 사용
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.green,
              ),
              const SizedBox(width: 12.0),
              Container(
                height: 50.0,
                width: 50.0,
                color: Colors.blue,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

▼ 출력 결과

 

MainAxisAlignment와 CrossAxisAlignment를 변경했을 때 어떤 UI를 구현할 수 있는지 표로 정리해두었으니 참고하기 바랍니다.

 

▼ MainAxisAlignment 옵션(예제는 모두 CrossAxisAlignment.center 기준입니다)

 

▼ CrossAxisAlignment 옵션(예제는 모두 MainAxisAlignment.center 기준입니다)

 

6.3 Flexible 위젯

Flexible 위젯은 Row나 Column에서 사용하는 위젯입니다. Flexible 위젯을 Column과 Row에서 사용하면 Flexible에 제공된 child가 크기를 최소한으로 차지하게 할 수 있습니다. 추가적으로 flex 매개변수를 이용해 각 Flexible 위젯이 얼만큼의 비율로 공간을 차지할지 지정할 수도 있습니다.

 

▼ Flexible 예제

Column(
 children: [
   Flexible(
     // flex는 남은 공간을 차지할 비율을 의미합니다.
     // flex값을 값을 제공하지 않으면 기본값은 1입니다.
     flex: 1,

     // 파란색 Container
     child: Container(
       color: Colors.blue,
     ),
   ),
   Flexible(
     flex: 1,

     // 빨간색 Container
     child: Container(
       color: Colors.red,
     ),
   )
 ],
),

 

▼ 파란색 flex: 1, 빨간색 flex: 1일 때

 

▼ 파란색 flex: 3, 빨간색 flex: 1일 때

 

6.4 Expanded 위젯

Expanded 위젯은 Flexible 위젯을 상속하는 위젯입니다. Column과 Row에서 Expanded를 사용하면 위젯이 남아 있는 공간을 최대한으로 차지합니다. 원리는 간단합니다. Flexible 위젯은 fit 매개변수에 FlexFit.tight 또는 FlexFit.loose를 입력할 수 있습니다. FlexFit.loose는 자식 위젯이 필요한 만큼의 공간만 차지합니다. 하지만 FlexFit.tight는 자식 위젯이 차지하는 공간과 관계없이 남은 공간을 모두 차지합니다. Expanded 위젯은 Flexible 위젯의 fit 매개변수에 FlexFit.tight를 기본으로 제공해준 위젯입니다. 그래서 Flexible 위젯과 다르게 남는 공간을 최대한으로 차지하게 됩니다.

 

▼ Expanded 예제

Column(
 children: [
   // 파란색 Container
   Expanded(
     child: Container(
       color: Colors.blue,
     ),
   ),
   // 빨간색 Container
   Expanded(
     child: Container(
       color: Colors.red,
     ),
   )
 ],
)

 

Expanded 위젯이 두 개이기 때문에 각 위젯이 남는 공간을 똑같이 나눠서 차지합니다. 이 비율은 Flexible과 마찬가지로 flex 매개변수의 값에 따라 변경됩니다.

 

6.5 Stack 위젯

Row와 Column 위젯은 각각 가로와 세로로 위젯을 배치하는 역할을 합니다. 반면 Stack 위젯은 위젯을 겹치는 기능을 제공해줍니다. 플러터의 그래픽 엔진인 스키아 엔진은 2D 엔진이기 때문에 겹친 두께를 표현하지는 못하지만 Stack을 사용하면 위젯 위에 위젯을 올린 듯한 효과를 줄 수 있습니다.

 

▼ Stack 예제

Stack(
 children: [
   // 빨간색 Container
   Container(
     height: 300.0,
     width: 300.0,
     color: Colors.red,
   ),

   // 노란색 Container
   Container(
     height: 250.0,
     width: 250.0,
     color: Colors.yellow,
   ),
              
   // 파란색 Container
   Container(
     height: 200.0,
     width: 200.0,
     color: Colors.blue,
   ),
 ],
),

 

Stack은 children에 위치한 순서대로 위젯을 겹치게 합니다. 빨간색 컨테이너, 노란색 컨테이너, 파란색 컨테이너 순서로 작성되었기 때문에 동일한 순서대로 위젯을 겹쳐갑니다. 컨테이너가 점점 가로, 세로 50픽셀씩 작아지고 있어 먼저 그려진 컨테이너가 가로 세로 50픽셀만큼 더 크게 그려집니다.

 

7. 기본 위젯 마무리

핵심 요약

  1. Text 위젯은 글자를 화면에 그릴 때 사용됩니다.
  2. 제스처 관련 위젯
  • Button 위젯은 TextButton, OutlinedButton, ElevatedButton이 있습니다.
  • IconButton 위젯은 아이콘을 버튼으로 만듭니다.
  • GestureDetector 위젯은 하위 위젯이 제스처에 반응하도록 해줍니다.
  • FloatingActionButton 위젯은 화면의 오른쪽 아래, 사용자가 가장 많이 사용하는 위치에 버튼을 띄우는 데 사용됩니다.
  1. 디자인 관련 위젯
  • Container 위젯은 위젯에 배경, 패딩, 테두리 등 디자인 요소를 추가하는 데 사용합니다.
  • SizedBox 위젯은 너비와 높이를 지정할 수 있는 위젯이며 흔히 위젯 사이의 간격을 구현할 때 많이 사용합니다.
  • Padding 위젯은 하위 위젯에 패딩을 적용할 때 사용합니다.
  • SafeArea 위젯은 시스템 UI에 가려지지 않게 위젯을 화면에 그릴 때 사용합니다.
  1. 배치 관련 위젯
  • Row 위젯은 가로로 위젯을 배치할 때 사용합니다.
  • Column 위젯은 세로로 위젯을 배치할 때 사용합니다.
  • Flexible 위젯은 Row나 Column에서 하위 위젯이 비율만큼 공간을 차지할 수 있게 해줍니다.
  • Expanded 위젯은 Row나 Column에서 하위 위젯이 최대한의 공간을 차지할 수 있게 해줍니다.
  • Stack 위젯은 하위 위젯들을 순서대로 겹쳐줍니다.

 

지금까지 앱을 만드는 데 자주 사용되는 위젯들을 알아봤습니다.

이 정도는 알아야 원활하게 앱을 만들 수 있으니 반복해서 학습하길 권합니다.

최지호(코드팩토리) 
임페리얼 칼리지 런던을 졸업하고 계리 컨설팅 회사 밀리만(Milliman) 한국 지사에서 소프트웨어 엔지니어로 일했습니다. 현재 주식회사 코드팩토리를 창업하여 개발을 하면서 초보자뿐만 아니라 현직 개발자에게도 유용한 개발 강의를 제작합니다. 밀리의서재 플러터 전환 차세대 프로젝트를 리드했습니다.

Leave a Reply

©2020 GoldenRabbit. All rights reserved.
상호명 : 골든래빗 주식회사
(04051) 서울특별시 마포구 양화로 186, 5층 512호, 514호 (동교동, LC타워)
TEL : 0505-398-0505 / FAX : 0505-537-0505
대표이사 : 최현우
사업자등록번호 : 475-87-01581
통신판매업신고 : 2023-서울마포-2391호
master@goldenrabbit.co.kr
개인정보처리방침
배송/반품/환불/교환 안내