플러터:변하는 화면(StatefulWidget)
둘러보기로 이동
검색으로 이동
개요[편집 | 원본 편집]
어플은 정적인 화면만으로 구성되진 않는다. 화면을 구성하는 요소에 변화를 주어야 하는데, 이때 상태(state)를 어떻게 관리하고 화면에 반영하는지가 매우 중요하다.
기본 카운터 앱 전체 코드[편집 | 원본 편집]
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo', // 앱 이름
debugShowCheckedModeBanner: false, // 오른쪽 상단의 "debug" 띠 제거
theme: ThemeData(
colorSchemeSeed: Colors.blue, // 전체적인 색상 팔레트 지정
),
home: const MyHomePage(title: 'Flutter Demo Home Page'), // 첫 화면
);
}
}
class MyHomePage extends StatefulWidget {
// StatefulWidget = 상태(state)를 가지고 변경 가능한 화면을 만들 때 사용
final String title; // 화면 상단 AppBar에 표시할 제목
const MyHomePage({super.key, required this.title});
@override
State<MyHomePage> createState() => _MyHomePageState();
// 이 위젯이 사용할 State 객체 생성
}
class _MyHomePageState extends State<MyHomePage> {
// 실제로 상태를 가지고 동작하는 부분은 여기(State 클래스)
int _counter = 0; // 화면에 표시될 숫자 상태 값 (초기값 = 0)
void _incrementCounter() {
// FloatingActionButton을 눌렀을 때 실행되는 함수
setState(() {
// setState()를 호출해야 화면을 다시 그리게(Rebuild) 된다. 이 함수 동작이 끝나면 이 상태를 다시 그림.
_counter++; // 상태 값 증가
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
// widget.title → 부모(StatefulWidget)에서 받은 title 값
),
body: Center( // Center = 가운데로 정렬
child: Column( // Column = 세로로 위젯을 쌓는 레이아웃
mainAxisAlignment: MainAxisAlignment.center, // mainAxisAlignment.center → 세로 가운데 정렬
children: [
const Text('You have pushed the button this many times:'),
// 설명 문장 (고정 텍스트이므로 const 사용)
Text(
'$_counter', // 화면에 상태 값 표시
style: Theme.of(context).textTheme.headlineMedium, // 앱 테마에서 지정된 큰 글씨 스타일 사용
),
],
),
),
floatingActionButton: FloatingActionButton( // 오른쪽 아래 떠있는 버튼 (FAB)
onPressed: _incrementCounter, // 버튼 클릭 → 상태에 정의된 함수 실행
tooltip: 'Increment', // 버튼 길게 누르면 뜨는 설명
child: const Icon(Icons.add), // + 아이콘
),
);
}
}
이해를 위한 추가 설명[편집 | 원본 편집]
| 요소 | 설명 | 비고 |
|---|---|---|
StatefulWidget
|
“상태를 가질 수 있는 위젯”. UI 틀(설계도) 역할
이를 상속한 클래스는 State를 작성해야 한다.class MyHomePage extends StatefulWidget {
// StatefulWidget = 상태(state)를 가지고 변경 가능한 화면을 만들 때 사용
final String title; // 화면 상단 AppBar에 표시할 제목
const MyHomePage({super.key, required this.title});
@override
State<MyHomePage> createState() => _MyHomePageState();
// 이 위젯이 사용할 State 객체 생성
createState의 반환은 _MyHomePageState 타입이다.
|
|
| State | class _MyHomePageState extends State<MyHomePage> {
// 실제로 상태를 가지고 동작하는 부분은 여기(State 클래스)
|
|
setState()
|
void _incrementCounter() {
setState(() {
_counter++;
});
}
State를 상속받은 클래스에서 setState가 하는 일(핵심 원리)
|
의문[편집 | 원본 편집]
State<MyHomePage> 대신 그냥 State로 쓰면 안되나?[편집 | 원본 편집]
상속이나 오버라이딩에서 자연스레 생기는 의문인데, State와 위젯을 안전하게 연결하기 위해선 위처럼 써야 한다. 그냥 State를 쓰면 일반 State와 연결되어 상위 위젯의 값을 사용할 수 없다.