Flutter 프로그램 기초

 

  • 위젯(Widget) : 요소의 구성(Configuration)을 기술하고 처리한다.
  • 요소(Element) : 트리의 특정 위치에서 위젯을 인스턴스화 한다.
  • 렌더 객체(RenderObject) : 크기, 레이아웃 등을 다루고 렌더링을 처리한다.

State 생성

트리의 특정 위치를 참조하는 BuildContext 존재

해당 BuildContext에 연결

연결된 각 BuildContext에 위젯 배치(인스턴스화)

요소(Element) 생성

 

 

기본 코드

main() -> runApp(HelloWorld()) -> HelloWorld() -> build() -> MaterialApp() -> Scaffold()
import 'package:flutter/material.dart';

main() => runApp(HelloWorld());
// 한줄로 표현 가능 : 다트 언어 문법
// void main(){ runApp(MyApp();} 과 같음


class HelloWorld extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(  // MaterialApp은 그림을 그리는데 필요한 도화지
        title: 'First Flutter App',
        home: Scaffold(
          // Scaffold() 위젯은 홈 위젯 트리를 구성하는 기본 요소인 
          // appbar, body, title, bottomNavigationBar 등을 제공
          appBar: AppBar(title: const Text('appBar title')),
          body: const Center(child: Text('body center text')),
        ));
  }
}

 

 


 

Stateful

  • 위젯의 수명동안 변경될 수 있는 상태를 유지
  • 최소 두 개 이상 클래스가 필요

1) StatefulWidget 클래스가 : StatefulWidget 클래스 그자체는 변경불가

2) State 클래스 의 인스턴스를 생성 : State 클래스가 위젯의 수명동안 상태를 유지

 

Stateful 샘플 코드
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  // const : 컴파일시 상수화
  // const는 변수 뿐 아니라 '값'에 붙어서 '상수 값'으로

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;
  // final : 런타임시 상수화
  // final은 변수 앞에 붙어서 '변수'를 상수로

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  dynamic _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter += (10 * 0.1);
    });
  }

  @override
  Widget build(BuildContext context) {
    print('build $_counter');
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '클릭할때 숫자가 변한다:',
            ),
            Text(
              '이번엔 [$_counter]',
              style: const TextStyle(
                  fontSize: 32,
                  color: Colors.blue,
                  fontWeight: FontWeight.w700),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '클릭하면 증가한다',
        child: const Icon(Icons.handshake),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Tree

클릭할때 마다 숫자 증가

 

 

 

StatelessWidget

  • 변경불가능immutable
  • 속성을 변경할 수 없음
  • 모든 값이 final
  • 화면을 구성할 때 최초 한 번만 build() 함수를 호출한 후 다시 호출하지 않는다

 

StatelessWidget 샘플코드
import 'package:flutter/material.dart';

void main() => runApp(NewMyHomePage());

class NewMyHomePage extends StatelessWidget {
  int _counter = 0;
  void _incrementCounter() {
    _counter++;
    print('_incrementCounter : $_counter');
  }

  @override
  Widget build(BuildContext context) {
    print('StatelessWidget 테스트');

    return MaterialApp(
      title: 'StatelessWidget Test App',
      home: Scaffold(
        appBar: AppBar(title: const Text('StatelessWidget Demo')),
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('data'),
            Text('$_counter', style: Theme.of(context).textTheme.displayLarge),
          ],
        )),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

debug console 에 값 증가가 확인 되지만

I/flutter (26564): StatelessWidget 테스트
I/flutter (26564): _incrementCounter : 1
I/flutter (26564): _incrementCounter : 2
I/flutter (26564): _incrementCounter : 3
I/flutter (26564): _incrementCounter : 4
I/flutter (26564): _incrementCounter : 5

App은 변경되지 않음

 

 

 

위젯의 생명주기

StatelessWidget 위젯
  • 한 번 만들어지면 갱신할 수 없으므로 생명주기가 없음(다른 화면으로 이동하면 종료)

 

 

StatefulWidget 위젯

createState()
상태 생성

 

 

 

mounted == true
위젯을 화면에 장착

initState()
위젯 초기화

didChangeDependencies()
의존성 변경시 호출

build()
화면에 표시

didUpdateWidget()
위젯 갱신
(부모 위젯이나 데이터 변경 시 호출)

setState()
위젯 상태 갱신
(화면 UI 변경 시, 플러터에서 제일 많이 호출되는 함수)

deactivate()
위젯 상태 관리 중지
(State 객체가 플러터의 구성트리에서 제거될때 호출)

dispose()
위젯 상태 관리 완전 종료
(State 객체를 영구적으로 소멸할때 호출)

mounted == false
State 객체가 소멸되면 생명주기 종료

 

 

 

 

 

@override

  • 상위 클래스에서 정의된 변수와 메소드의 내용을, 하위 클래스에서 변경하여 재정의 하는 것
  • 새롭게 재정의하여, 상위 클래스 수행 기능과는 다른 기능을 수행케 하는 것
  1. 변수나 메소드의 내용을 변경할 수 있음
  2. 동일한 메소드 호출에도 각 객체 마다 다른 행동이 가능
  3. 자식 클래스는 새로운 클래스 역할도 가능
  • 함수 덮어쓰기
  1. 부모클래스의 함수를 재정의할때 표시