-
플러터 시작하기 - 2. 위젯Flutter/Learn Flutter 2025. 4. 29. 08:59반응형
Flutter와 관련하여, "모든 것이 위젯이다"라는 말을 자주 듣게 될 것입니다. 위젯은 Flutter 앱 사용자 인터페이스의 구성 요소이며, 각각의 위젯은 사용자 인터페이스의 일부를 불변(immutable)으로 선언하는 것입니다. 위젯은 텍스트와 버튼 같은 물리적 측면뿐만 아니라 패딩과 정렬 같은 레이아웃 효과를 설명하는 데에도 사용됩니다.
위젯은 구성(composition)을 기반으로 하는 계층 구조를 형성합니다. 각 위젯은 부모 안에 중첩되며 부모로부터 컨텍스트(context)를 받을 수 있습니다. 이 구조는 최상위(root) 위젯까지 이어집니다. 다음은 이를 보여주는 간단한 예제입니다.
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( // Root widget home: Scaffold( appBar: AppBar( title: const Text('My Home Page'), ), body: Center( child: Builder( builder: (context) { return Column( children: [ const Text('Hello, World!'), const SizedBox(height: 20), ElevatedButton( onPressed: () { print('Click!'); }, child: const Text('A button'), ), ], ); }, ), ), ), ); } }
위 코드에서는 인스턴스화된 모든 클래스가 위젯입니다: MaterialApp, Scaffold, AppBar, Text, Center, Builder, Column, SizedBox, ElevatedButton.
위젯 구성
Flutter는 위젯을 구성 단위로 강조합니다. 위젯은 일반적으로 여러 개의 작은 단일 목적의 위젯을 조합하여 강력한 효과를 만들어냅니다.
Padding, Alignment, Row, Column, Grid와 같은 레이아웃 위젯이 있습니다. 이러한 레이아웃 위젯은 자체적으로 시각적 표현이 없습니다. 대신 다른 위젯의 레이아웃을 제어하는 것이 목적입니다.
Flutter는 이러한 구성 방식을 활용하는 유틸리티 위젯들도 포함하고 있습니다. 예를 들어, 흔히 사용되는 Container 위젯은 레이아웃, 페인팅, 포지셔닝, 크기 조절을 담당하는 여러 위젯으로 이루어져 있습니다.
시각적 표현을 가지는 위젯도 있습니다. 예를 들어, 앞서 예제에 등장한 ElevatedButton과 Text, 그리고 Icon이나 Image 같은 위젯이 있습니다.
앞선 예제 코드를 실행하면, Flutter는 텍스트 "Hello, World!"와 버튼을 화면 중앙에 수직으로 배치하여 표시합니다. 여기서 요소들을 배치하기 위해 Center 위젯이 사용되어 자식들을 가능한 공간 중앙에 위치시키고, Column 위젯이 사용되어 자식들을 수직으로 나열합니다.
위젯 빌드하기
Flutter에서 사용자 인터페이스를 만들기 위해서는 위젯 객체에서 build 메서드를 오버라이드해야 합니다. 모든 위젯은 반드시 build 메서드를 가져야 하며, 이 메서드는 다른 위젯을 반환해야 합니다. 예를 들어, 텍스트에 패딩을 추가하여 화면에 표시하고 싶다면 이렇게 작성할 수 있습니다.
class PaddedText extends StatelessWidget { const PaddedText({super.key}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(8.0), child: const Text('Hello, World!'), ); } }
Flutter에서는 화면에 무언가를 보여주려면 build 메서드를 사용합니다. build 메서드는 "화면을 어떻게 그릴지"를 결정하는 역할을 합니다. 그런데 이 build 메서드는 앱이 시작될 때 한 번만 호출되는 게 아니라, 화면에 변할 일이 생길 때마다(예를 들면 버튼을 눌러 숫자가 바뀌었을 때처럼) 또다시 호출될 수 있습니다. 심지어, 매 프레임(초당 60번 이상!)마다 호출될 수도 있습니다.
그래서 중요한 규칙이 있습니다. build 메서드는 화면을 만드는 것만 하고, 파일 저장, 네트워크 요청, 데이터베이스 수정 같은 작업은 절대 하면 안 됩니다. 왜냐하면 build가 자주 호출되기 때문에, 만약 그런 부작용을 넣으면 앱이 느려지거나 엉망이 될 수 있기 때문입니다.
위젯 상태
프레임워크는 위젯을 두 가지 주요 클래스로 구분합니다:
- StatelessWidget
- 변경 가능한 상태가 없는 위젯
- 예: Padding, Text, Icon
- 대부분의 경우 직접 위젯을 만들 때는 StatelessWidget을 작성하게 됩니다.
- StatefulWidget
- 사용자 상호작용이나 다른 요인에 따라 상태가 변하는 위젯
- 예를 들어, 버튼을 누를 때마다 카운터가 증가하는 위젯은 StatefulWidget입니다.
- 값이 변할 때마다 위젯을 다시 빌드하여 UI를 업데이트해야 합니다.
StatefulWidget의 예제는 다음과 같습니다. StatefulWidget 자체에는 build 메서드가 없고, 대신 사용자 인터페이스는 해당 위젯의 State 객체를 통해 build가 이루어집니다.
class CounterWidget extends StatefulWidget { @override State<CounterWidget> createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Text('$_counter'); } }
State 객체를 변경(예: 카운터를 증가)할 때마다, 반드시 setState를 호출하여 프레임워크에 UI를 다시 빌드해야 한다고 신호를 보내야 합니다.
상태(state)를 위젯 객체와 분리함으로써, 다른 위젯들은 StatelessWidget과 StatefulWidget을 똑같이 취급할 수 있습니다. 부모는 자식 위젯의 상태를 유지하기 위해 별도로 관리할 필요 없이 언제든지 자식 위젯의 새 인스턴스를 생성할 수 있습니다. 프레임워크는 기존 State 객체를 찾아서 적절하게 재사용하는 모든 작업을 자동으로 처리합니다.
알아야 할 중요한 위젯들
Flutter SDK에는 Text와 같은 가장 작은 UI 구성 요소부터, 레이아웃 위젯, 애플리케이션 스타일링 위젯까지 다양한 빌트인 위젯이 포함되어 있습니다. 다음 위젯들은 알아두어야 할 가장 중요한 위젯들입니다:
- Container
- Text
- Scaffold
- AppBar
- Row와 Column
- ElevatedButton
- Image
- Icon
목차
반응형'Flutter > Learn Flutter' 카테고리의 다른 글
플러터 시작하기 - 5. 사용자 입력 처리 (2) 2025.04.29 플러터 시작하기 - 4. 상태 관리 (0) 2025.04.29 플러터 시작하기 - 3. 레이아웃 (0) 2025.04.29 플러터 시작하기 - 1. 다트 소개 (1) 2025.04.29 플러터 시작하기 - 0. 개요 (0) 2025.04.29 - StatelessWidget