FrameWorks/Flutter

3. Stateful Widgets

ABCD 2023. 4. 24.

State

Stateful Widget

  • Stateless Widget ← 데이터 없이 단순히 UI만 만듬
  • 위젯에 데이터를 저장하고 싶을 때 사용
  • 실시간으로 데이터의 변화를 보고 싶을 때 사용
  • StatelessWidget을 StatefulWidget으로 변경할 수 있음

Stateful Widget의 종류

  • 데이터가 없는 위젯
  • 데이터가 있는 위젯
    • 데이터에 따라 UI가 변경될 수도 있음

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

	@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFFF4EDDB),
        body: Container()
			)
    );
  }
}


SetState

  • 메서드를 작성 후 그냥 버튼을 눌렀을 때에는 화면이 새로 고쳐지지 않아 UI가 변하지 않는다.
  • 따라서, 화면을 새로 고침 하기 위해 setState(( ){ }); 안에 함수로직을 넣어주어야 새로고침이 된다.
  • UI가 다시 최근 데이터를 반영하여 새로 build하는 방식

ex) counter가 증가하는 로직

class _MyAppState extends State<MyApp> {
  int counter = 0;

  void onClicked() {
    setState(() { //반드시 넣어야 함
      counter++;
    });
  }

	//또는 이렇게 작성해도 가능
	void onClicked() {
		counter++;
    setState(() {}); //반드시 넣어야 함
  }
}

  • 위젯에 반복문을 사용하여 새로운 객체를 계속 생성하면서 UI에 반영 할 수 있다.
@override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFFF4EDDB),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                "Click Count",
                style: TextStyle(
                  fontSize: 30,
                ),
              ),
              for (var n in numbers) Text("${n}"),
              IconButton(onPressed: onClicked, icon: Icon(Icons.add)),
            ],
          ),
        ),
      ),
    );
  }


BuildContext

  • 부모의 요소에 접근 할 수 있게 해주는 객체
  • 부모의 부모의 부모의 부모의 ~~~~~ 까지 가능
  • theme 객체를 사용하여 default 값을 정해주고 꺼내서 특정 요소의 사용이 가능 하다.
  • 아래 MyLargeTitle처럼 명시하며 null이 아님을 표시해주기 위해 !를 삽입하여 준다.
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<int> numbers = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        textTheme: TextTheme(
          titleLarge: TextStyle(
            color: Colors.red,
          ),
        ),
      ),
      home: Scaffold(
        backgroundColor: Color(0xFFF4EDDB),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              MyLargeTitle(),
            ],
          ),
        ),
      ),
    );
  }
}

class MyLargeTitle extends StatelessWidget {
  const MyLargeTitle({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Text(
      "My Large Title",
      style: TextStyle(
        fontSize: 30,
        color: Theme.of(context).textTheme.titleLarge!.color,
      ),
    );
  }
}


Widget LifeCycle

initState

  • 상태를 초기화하기 위해 존재하는 메서드
  • 종종 부모 요소에 의존하는 데이터를 초기화하기 위해 존재한다.
  • 단 한번만 호출된다.
  • 꼭 필요하지는 않다.
  • build메서드보다 항상 먼저 실행되어야 한다.

dispose

  • 위젯이 스크린에서 제거 될 때 자동으로 실행되는 메서드
  • 무언가를 취소 할 때 사용하는 메서드

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool textBool = true;

  void button() {
    setState(() {
      textBool = !textBool;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        textTheme: TextTheme(
          titleLarge: TextStyle(
            color: Colors.red,
          ),
        ),
      ),
      home: Scaffold(
        backgroundColor: Color(0xFFF4EDDB),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              textBool ? MyLargeTitle() : Text("Nothing!!"),
              IconButton(onPressed: button, icon: Icon(Icons.school)),
            ],
          ),
        ),
      ),
    );
  }
}

class MyLargeTitle extends StatefulWidget {
  const MyLargeTitle({
    super.key,
  });

  @override
  State<MyLargeTitle> createState() => _MyLargeTitleState();
}

class _MyLargeTitleState extends State<MyLargeTitle> {
  @override
  void initState() {
    super.initState();
    print("init!!!");
  }

  @override
  void dispose() {
    super.dispose();
    print("dispose!!!!!!!Wow!!!!");
  }

  @override
  Widget build(BuildContext context) {
    print("Hello!!");
    return Text(
      "My Large Title",
      style: TextStyle(
        fontSize: 30,
        color: Theme.of(context).textTheme.titleLarge!.color,
      ),
    );
  }
}

Uploaded by N2T

728x90
반응형

'FrameWorks > Flutter' 카테고리의 다른 글

2. UI Challenge  (0) 2023.04.10
1. Hello Flutter  (0) 2023.04.10
Flutter??  (0) 2023.04.10
[Flutter] 객체 생성시 Const를 붙이라는 Warning 제거  (0) 2023.04.09

댓글

💲 추천 글