Flutter 프로그램 기초
2022.04.05
- 위젯(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
- 상위 클래스에서 정의된 변수와 메소드의 내용을, 하위 클래스에서 변경하여 재정의 하는 것
- 새롭게 재정의하여, 상위 클래스 수행 기능과는 다른 기능을 수행케 하는 것
- 변수나 메소드의 내용을 변경할 수 있음
- 동일한 메소드 호출에도 각 객체 마다 다른 행동이 가능
- 자식 클래스는 새로운 클래스 역할도 가능
- 함수 덮어쓰기
- 부모클래스의 함수를 재정의할때 표시