1. 상태(State)란?
Flutter에서 "상태"는 위젯의 UI와 동작을 결정하는 데이터의 모음으로, 주로 UI에 반영되는 정보를 의미합니다.
이게 무슨 뜻인지 예시를 통해 알아보겠습니다.
어떤 버튼이 주어지고, 이 버튼이 몇번 눌렸는지를 표현하는 숫자가 출력되는 페이지가 있습니다.
처음에는 버튼을 누른 적이 없으므로, 버튼을 누른 횟수가 0회로 나타나야합니다. 하지만 이후에 버튼을 클릭하게 되면 버튼을 누른 횟수가 1씩 증가하여야합니다.
위 이미지는 버튼을 누른 뒤에 누른 횟수가 1이 증가하여 표시되는 모습입니다. 이때 숫자 "1"은 상태(State)를 나타내는 데이터입니다.
2. StatefulWidget과 StatelessWidget
방금 살펴본 예시에서는 총 2가지 텍스트가 존재했습니다. "버튼을 누른 횟수:"와 숫자 "0" 또는 "1" 이었습니다.
버튼을 누를 때 마다 상태가 변경되며 숫자의 값이 증가하였지만, "버튼을 누른 횟수:"라는 문구는 전혀 변경되지 않았습니다. 이는 2가지 텍스트는 다른 방법(위젯)으로 구현되었기 때문입니다.
2-1. StatelessWidget
StatelessWidget은 상태가 없는 위젯입니다. 그러므로, 위젯이 한 번 생성되면 변경되지 않습니다. 표시할 정보가 변경될 일이 없다면 해당 위젯을 사용합니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text(
'이것은 StatelessWidget 입니다.',
style: TextStyle(fontSize: 24),
),
),
),
);
}
}
2-2. StatefulWidget
StatefulWidget은 변화할 수 있는 상태를 갖는 위젯입니다. 상태를 변경시킴으로써 UI가 다시 그려질 수 있다는 특징이 있습니다.
아래는 버튼을 눌렀을 때, 버튼을 누른 횟수가 출력되도록 하는 예제입니다. 소스코드 아래쪽에 설명을 첨부하겠습니다.
import 'package:flutter/material.dart';
// 앱의 메인 부분입니다.
void main() {
runApp(MyApp());
}
// MyApp은 앱 전체를 나타내는 위젯입니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}
// CounterScreen은 숫자를 보여주고 증가시키는 화면입니다.
class CounterScreen extends StatefulWidget {
@override
_CounterScreenState createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
int counter = 0; // 숫자를 저장하는 변수입니다.
void _incrementCounter() {
setState(() {
counter++; // 버튼을 누르면 숫자가 1씩 증가합니다.
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('숫자: $counter'),
ElevatedButton(
onPressed: _incrementCounter, // 버튼을 누르면 숫자가 증가합니다.
child: Text('숫자 증가'), // 버튼의 텍스트입니다.
),
],
),
),
);
}
}
2-2-1. 예제 분석
앱의 메인 부분(함수)입니다. MyApp() 최상위 위젯을 실행합니다.
void main() {
runApp(MyApp());
}
최상위 위젯인 MyApp()을 선언(구조/기능 정의)합니다. MyApp()은 StatelessWidget을 상속받습니다. 쉽게 말하자면, StatelessWidget 클래스가 갖고 있는 기능과 데이터들을 그대로 MyApp 클래스에서 사용 가능하게 만듭니다.
@override 를 통해 build 메서드를 재정의 합니다. build 메서드는 Widget 타입을 반환(return)합니다. home 속성에 속성 값으로 CounterScreen()을 갖는 MaterialApp 위젯을 반환하도록 구현하였습니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterScreen(),
);
}
}
CounterScreen() 클래스를 선언합니다. CounterScreen() 클래스는 StatefulWidget() 클래스를 상속받습니다. 이를 통해 CounterScreen() 클래스는 상태를 가질 수 있습니다. StatefulWidget 클래스의 createState() 메소드를 재정의(override)합니다. createState() 메서드는 _CounterScreenState() 객체를 반환합니다. createState() 메서드는 StatefulWidget의 필수 메서드이기에 반드시 선언해주어야합니다.
참고 : StatefulWidget은 상태를 관리할 수 있는 위젯을 정의(생성)만 가능하고, 로직(동작 또는 기능)은 State 클래스로 분리되어있습니다. 즉, 실제 상태 관리 로직은 MyApp 클래스와 연결된 State 클래스에서 처리됩니다.
class CounterScreen extends StatefulWidget {
@override
_CounterScreenState createState() => _CounterScreenState();
}
상태 관리 클래스(State)가 CounterScreen 위젯의 상태를 관리하도록 하는 State<CounterScreen> 클래스를 상속받는 _CounterScreenState 클래스를 선언합니다.
State 클래스는 setState를 통해 상태를 변경하고 이를 화면에 적용하도록 합니다. _incrementCounter() 메서드에 counter 변수(또는 상태)를 1 증가시킨 뒤, setState로 이를 화면에 적용시킵니다.
StatelessWidget과는 달리, StatefulWidget 자체에는 build 메서드가 없습니다. 대신 StateWidget과 연결된 State 클래스에 build 메서드가 존재합니다. 이를 이용하여 counter 상태를 출력하고, 누르면 counter 상태 값이 1증가하는 버튼을 화면에 표시합니다.
class _CounterScreenState extends State<CounterScreen> {
int counter = 0; // 숫자를 저장하는 변수입니다.
void _incrementCounter() {
setState(() {
counter++; // 버튼을 누르면 숫자가 1씩 증가합니다.
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('숫자: $counter'),
ElevatedButton(
onPressed: _incrementCounter, // 버튼을 누르면 숫자가 증가합니다.
child: Text('숫자 증가'), // 버튼의 텍스트입니다.
),
],
),
),
);
}
}
'웹 · 앱 개발 > 플러터(Flutter)' 카테고리의 다른 글
Flutter 4화 - 비동기 프로그래밍 (0) | 2024.08.10 |
---|---|
Flutter 3화 - UI 기초(클래스, 객체, 속성, Text) (0) | 2024.08.10 |
Flutter 2화 - Dart 문법 학습하기 (0) | 2024.08.10 |
Flutter 1화 - Flutter 설치 및 예제 (0) | 2024.08.10 |