플러터:변하는 화면(StatefulWidget): 두 판 사이의 차이
보이기
잔글 →개요 |
편집 요약 없음 |
||
| 4번째 줄: | 4번째 줄: | ||
화면 변화 반영하기. | 화면 변화 반영하기. | ||
어플은 정적인 화면만으로 구성되진 않는다. 화면을 구성하는 요소에 변화를 주어야 하는데, 이때 상태(state)를 어떻게 관리하고 화면에 반영하는지가 매우 중요하다. | * 어플은 정적인 화면만으로 구성되진 않는다. 화면을 구성하는 요소에 변화를 주어야 하는데, 이때 상태(state)를 어떻게 관리하고 화면에 반영하는지가 매우 중요하다. | ||
* 처음 개념 잡기가 어려운데, 천천히 따라가보길. | |||
=== 기본 방식 === | |||
* StatefulWidget을 제작하여 createState 함수를 오버라이딩 함. 단순하게 특정 상태를 반환한다는 내용. | |||
* 특정 상태는 정의되어 있지 않기 때문에 State를 작성하여 build 함수를 오버라이딩 함. | |||
* 변화를 가할 함수를 상태 내부에 작성함. 해당 함수에서 setState 함수가 작동하게끔 구성. | |||
* setState 함수의 작동이 끝나면 StatefulWidget에 다시 그리라는 신호를 보냄, 그러면 StatefulWidget이 State를 기반으로 다시 작성됨. | |||
= 기본 카운터 앱 전체 코드 = | = 기본 카운터 앱 전체 코드 = | ||
아래는 기본적으로 많이 제공되는 예시인 기본 카운터 앱이다.<syntaxhighlight lang="dart"> | 아래는 기본적으로 많이 제공되는 예시인 기본 카운터 앱이다.<syntaxhighlight lang="dart"> | ||
| 22번째 줄: | 31번째 줄: | ||
colorSchemeSeed: Colors.blue, // 전체적인 색상 팔레트 지정 | colorSchemeSeed: Colors.blue, // 전체적인 색상 팔레트 지정 | ||
), | ), | ||
home: const MyHomePage(title: 'Flutter Demo Home Page'), // 첫 화면 | home: const MyHomePage(title: 'Flutter Demo Home Page'), // 첫 화면. 굳이 변수로 전달할 필요는 없어 보이는데, 예제에선 학습용으로 둔 듯. | ||
); | ); | ||
} | } | ||
2026년 1월 7일 (수) 00:38 기준 최신판
- 플러터:개요
- 플러터:실행
- 플러터:개념 잡기
- 권한 사용
- 위젯
- 플러터:DB연결
- 플러터:Firebase(미완)
- 플러터:MySQL(미완)
- 디자인
- 플러터:배포
- 플러터:참고자료
- 플러터:위젯
- 플러터:라이브러리
화면 변화 반영하기.
- 어플은 정적인 화면만으로 구성되진 않는다. 화면을 구성하는 요소에 변화를 주어야 하는데, 이때 상태(state)를 어떻게 관리하고 화면에 반영하는지가 매우 중요하다.
- 처음 개념 잡기가 어려운데, 천천히 따라가보길.
- StatefulWidget을 제작하여 createState 함수를 오버라이딩 함. 단순하게 특정 상태를 반환한다는 내용.
- 특정 상태는 정의되어 있지 않기 때문에 State를 작성하여 build 함수를 오버라이딩 함.
- 변화를 가할 함수를 상태 내부에 작성함. 해당 함수에서 setState 함수가 작동하게끔 구성.
- setState 함수의 작동이 끝나면 StatefulWidget에 다시 그리라는 신호를 보냄, 그러면 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와 위젯을 안전하게 연결하기 위해선 위처럼 써야 한다. 그냥 State를 쓰면 일반 State와 연결되어 상위 위젯의 값을 사용할 수 없다.