플러터:변하는 화면(StatefulWidget)

학교의 모든 지식. SMwiki
둘러보기로 이동 검색으로 이동

틀:플러터 Dart:개요 플러터에 대한 지식 분류

  1. 플러터:개요
    1. 플러터:VSCode
  2. 플러터:실행
  3. 개념 잡기
    1. 플러터:화면 하나 만들기
    2. 플러터:변하는 화면(StatefulWidget)
    3. 플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)
    4. 플러터:화면 전환(Drawer)
    5. 플러터:키보드 입력
    6. 플러터:슬라이더
    7. 플러터:그래프 그리기(fl chart)
    8. 플러터:데이터 저장(간단한 데이터)
    9. 플러터:인증(Firebase 인증)
    10. 플러터:인증(OAuth2)
  4. 권한 사용
    1. 플러터:마이크 입력
  5. 위젯
    1. 플러터:아이콘
    2. 플러터:레이아웃 계열 위젯
    3. 플러터:네비게이션 계열 위젯
    4. 플러터:버튼
    5. 플러터:상태관리
  6. 플러터:DB연결
    1. 플러터:Firebase
    2. 플러터:MySQL
  7. 디자인
    1. 플러터:테마
    2. 플러터:앱바
    3. 플러터:버튼
  8. 플러터:배포
  9. 플러터:참고자료
  10. 플러터:위젯
    1. 플러터:공간배치용 위젯
  11. 플러터:라이브러리
    1. 플러터:logger

개요[편집 | 원본 편집]

어플은 정적인 화면만으로 구성되진 않는다. 화면을 구성하는 요소에 변화를 주어야 하는데, 이때 상태(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를 오버라이딩하는데, 타입은 State인데, 또 State 타입은 MyHomePage이고,

createState의 반환은 _MyHomePageState 타입이다.

_MyHomePageState 객체를 반환하여 Flutter가 화면 상태 관리(State)를 연결하도록. 결과적으로 새로운 State가 생성된다.

State
class _MyHomePageState extends State<MyHomePage> {
  // 실제로 상태를 가지고 동작하는 부분은 여기(State 클래스)
  • State를 상속받는데, MyHomePage를 타입으로 한 State를 상속받는다.
  • State 안에서는 부모 StatefulWidget의 프로퍼티를 widget으로 접근한다.
setState()
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
setState는 함수를 인자로 받는 함수이며, () {} 는 익명함수의 구조이다.

State를 상속받은 클래스에서 setState()을 사용하면, 이 함수의 동작이 끝날 때 해당 클래스에 대한 것들을 새로 그린다.

setState가 하는 일(핵심 원리)

  1. _counter를 변경.
  2. 해당 State의 build() 함수를 다시 호출.
  3. 화면(UI)이 새 값을 반영해 다시 그려짐.

의문[편집 | 원본 편집]

State<MyHomePage> 대신 그냥 State로 쓰면 안되나?[편집 | 원본 편집]

상속이나 오버라이딩에서 자연스레 생기는 의문인데, State와 위젯을 안전하게 연결하기 위해선 위처럼 써야 한다. 그냥 State를 쓰면 일반 State와 연결되어 상위 위젯의 값을 사용할 수 없다.