오늘은 Flutter 프로젝트의 가장 기본이 되는 Widget들인 StatelessWidget & StatefulWidget과 Scaffold에 대해 소개하도록 하겠습니다.
Widget 이란?
Flutter에서 Widget은 화면의 모든 요소를 나타내는 기본 단위입니다. 텍스트, 이미지, 버튼, 레이아웃 등 모든 UI 요소는 Widget으로 표현됩니다.
Flutter의 Widget은 계층 구조로 구성됩니다.
가장 상위 Widget은 MaterialApp
위젯이며, 이 위젯 아래에 다른 Widget들이 계층 구조로 배치됩니다.
Widget은 다수의 서브트리를 동시에 구성할 수 있는 불변 객체입니다.
Widget이 트리에 배치될 때마다 Element로 instance화 되므로 Element는 특정 트리 위치에서 Widget을 대표한다고 볼 수 있습니다.
Widget Tree
Flutter의 위젯 트리는 Flutter 애플리케이션에서 사용자 인터페이스를 구축하기 위한 계층적 구조입니다.
이 구조는 여러 위젯들의 배열과 관계를 나타내며, 각 위젯은 UI의 기본 구성 단위로 동작합니다. 위젯 트리는 복잡한 UI 디자인을 중첩과 조합을 통해 가능하게 하며, UI 요소들의 렌더링과 상태 관리를 효율적으로 관리합니다.
이 트리 구조는 각 위젯이 전체 UI 레이아웃에서 자신의 역할과 위치를 알 수 있도록 도와줍니다.

Widget 분류
Flutter에서는 다양한 Widget들이 존재하는데 크게 StatelessWidget과 StatefulWidget으로 나뉩니다.
Flutter의 가장 기본이 되는 Layout 위젯인 Scaffold 까지 소개하고자 합니다.
StatelessWidget 이란?
개요
StatelessWidget
은 상태가 없는 위젯입니다.
이는 위젯의 생성 시점에 모든 구성이 결정되며, 데이터 변경에 따라 다시 Rendering 되지 않습니다.
간단히 말해, 어떤 입력에 의해서 특정 상태(값)이 변경되지 않는 Widget을 의미합니다.

특징
- 성능이 좋습니다. 데이터가 변경되지 않기 때문에 리소스를 적게 사용합니다.
build
() 메소드는 위젯 생성 시 한 번만 호출됩니다.
사용예
정적인 데이터를 표시할 때 사용합니다.
Ex) Text Label, Icon, Image와 같이 앱이 실행되는 동안 변경되지 않는 UI 요소에 적합합니다.
예제코드
build()
메서드에서, ‘StatelessWidget Example’이라는 텍스트를 중앙에 표시하고 별도의 상태 변화를 제공하지 않습니다.
class MyStatelessWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Text('StatelessWidget Example'), ); } }
결과

StatefulWidget 이란?
개요
StatefulWidget
은 상태가 있는 위젯입니다.
이는 동적 데이터를 관리하고, 데이터가 변경될 때마다 UI가 업데이트될 수 있습니다.
특징
- 동적인 상호작용을 지원합니다.
State
객체를 통해 상태 관리가 이루어지며,setState
메소드를 호출하면build
메소드가 다시 실행되어 UI가 업데이트됩니다.

사용예
사용자 상호작용이나 데이터 변경에 응답하여 UI를 업데이트해야 할 때 사용합니다.
예를 들어, 폼 필드, 체크 박스, 혹은 사용자 인터랙션이 있는 모든 요소에 사용됩니다.
예제코드
다음 예제에서는 text
라는 상태값이 버튼을 눌렀을 때, setState() 메소드 안에서 text
값이 변경 되고,
해당 상태가 업데이트 되어 Rendering 됩니다.
import 'package:flutter/material.dart'; class MyStatefulPage extends StatefulWidget { const MyStatefulPage({super.key}); @override _MyStatefulPageState createState() => _MyStatefulPageState(); } class _MyStatefulPageState extends State<MyStatefulPage> { String text = 'StatefulWidget Example'; @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( text, textAlign: TextAlign.center, style: const TextStyle(fontSize: 30), ), ElevatedButton( onPressed: () { setState(() { text = 'State is Changed!'; }); }, child: const Text('Button'), ), ], ), ); } }
결과

Scaffold 란?
개요
Scaffold
는 기본적인 Material Deisgn Layout 구조를 구현하는 데 사용됩니다.
Scaffold
위젯은 앱의 기본 구조를 제공하며, 여러 Child Widget들과 함께 사용될 수 있는 빌딩 블록입니다.
기능
- AppBar: 페이지의 상단에 표시되는 앱 바를 제공합니다. 앱 바에는 애플리케이션의 제목, 탐색 버튼, 상태 표시줄 등이 포함될 수 있습니다.
- body: 페이지의 본문 콘텐츠를 제공합니다. 텍스트, 이미지, 버튼, 레이아웃 등 다양한 위젯을 사용하여 구성할 수 있습니다.
- floatingActionButton: 페이지의 하단에 표시되는 플로팅 버튼을 제공합니다. 플로팅 버튼은 일반적으로 주요 기능을 수행하는 데 사용됩니다.
속성
속성 | 설명 |
---|---|
AppBar | 화면 상단에 위치하며 앱의 타이틀, 액션 아이템, 오버플로우 메뉴 등을 포함할 수 있습니다. |
Body | 앱의 주요 콘텐츠가 표시되는 부분으로, 다양한 위젯들을 이곳에 배치할 수 있습니다. |
FloatingActionButton | 화면에 부동하는 버튼으로, 일반적으로 액션을 유도하는 메인 기능에 사용됩니다. |
BottomNavigationBar | 화면 하단에 위치하는 네비게이션 바로, 여러 탭으로 구성될 수 있습니다. |
Drawer | 화면의 옆에서 슬라이드하여 나오는 메뉴로, 네비게이션 링크나 옵션을 포함할 수 있습니다 |
SnackBar | 간단한 메시지를 잠깐 동안 보여주는데 사용되며, 화면 하단에 일시적으로 표시됩니다. |
BottomSheet | 화면 하단에서 올라오는 패널로, 추가 정보나 입력 폼을 제공할 수 있습니다. |
예제
이 코드는 간단한 Flutter 애플리케이션의 Scaffold 예제입니다.
AppBar에는 애플리케이션의 제목이 표시되고, body에는 각 종 주요 표시 Widget들이 표시되고
floatingActionButton에는 Floating Button으로 Action을 할수 있는 버튼이 표시됩니다.
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
결과
