super(): 부모 클래스의 생성자 호출
class DialPhone {
int? year;
DialPhone() {
print("다이얼을 돌려서 전화를 겁니다");
}
void whenCame() {
print("188년에 발명되었습니다 $year");
}
}
class ButtonPhone extends DialPhone {
int? to;
ButtonPhone() {
print("이 전화기는 버튼을 눌러서 전화를 겁니다");
}
@override
void whenCame() {
print("1963년 발명 $year $to");
}
}
class SmartPhone extends ButtonPhone {
String maker;
String model;
SmartPhone({required this.maker, required this.model, int? year, int? to}) : super() {
super.year = year;
super.to = to;
}
}
void main() {
SmartPhone sp = new SmartPhone(maker:"애플", model: "아이폰20", year:30,to:50);
sp.whenCame();
}
// print 결과 ▼
// 다이얼을 돌려서 전화를 겁니다
// 이 전화기는 버튼을 눌러서 전화를 겁니다
// 1963년 발명 30 50
일회성 UI 요소로 사용되며 상태가 바뀌어야할 때 기존 위젯을 제거하고 새롭게 위젯을 생성
내부적으로 abstract 형식으로 Stateless 가 정의되어있음
그래서 build 메소드의 경우 자식 클래스에서 재정의 해주어야함
추상클래스 abstract
body{} 가 없는 메소드의 경우 반드시 자식 요소에서 재정의 해주어야함
abstract class Animal{
void makeSound();
}
class Dog extends Animal{
@override
void makeSound(){
print("왈왈");
}
}
void main(){
Dog dog = Dog();
dog.makeSound();
}
Widget tree
이렇게 그려줘라고 지시하는 설계도 역할
Element tree
Widget tree와 렌더 트리 중간에서 서로를 연결시키면서 앱의 효율적인 UI 업데이트를 관리
Widget tree가 생성될때마다 이에 근거해서 flutter 프레임워크가 즉시 함께 생성하고 컨트롤해줌 따라서 Widget tree의 모든 위젯은 1대1 맞대응 형식으로 Element tree에 링크되어 있음
연결된 Widget 의 모든 정보를 가지고 있음 ( 위치, 타입, 크기, 배경색 등..)
그래서 어떤 Widget 의 상태가 변경되어서 빌드 메소드가 호출되고 Widget tree 가 리빌드 된다면 이와 연결되어 있는 Element tree 도 함께 리빌드 되는것이 아닌 새롭게 리빌드된 Widget 의 위치나 타입 속성등이 이전 Widget과 일치하면 이전 Widget과의 연결을 끊고 새롭게 생성된 Widget 인스턴스로 링크만 업데이트해줌 렌더 트리가 이 부분을 다시 앱 화면에 그려주게 됨 그 외 상태 변화가 없는 Widget들은 그대로 유지

Render tree
UI 를 실제로 화면에 표시하기 위해서 각 위젯의 위치와 크기를 계산하고 그리는 역할

예를 들어 앱의 특정 텍스트 위젯에 전달되는 문자열이 setState 를 통해 바뀌었다면 기존 텍스트 위젯을 그대로 수정하는것이 아니라 빌드 메소드를 다시 호출하여 완전히 새로운 텍스트 위젯 인스턴스를 생성

Widget이 바뀌면 무조건 새로운 Widget 만들어지고,
Element는 조건이 맞으면 재사용되고, (매핑된 새 Widget과 기존 Widget의 runtimeType과 key가 동일할 때, 즉 직접적으로 key 를 선언하여 명시하거나, Text 위젯에서 Icon 위젯처럼 변경하지 않는 이상 리빌드 되지 않음 )
RenderObject는 실제 렌더링에 영향이 있을 때만 layout/paint 된다.
Widget tree 내에서 변경된 부분은 새롭게 Widget이 만들어지고 Element tree 는 기존 Widget 은 버리고 새롭게 만들어진 Widget 과 링크해주고, 그외 변경되지 않은 Widget들은 재사용
Stateless 위젯과 거의 동일하게 동작하는데, 가장 큰 차이는 Stateful 위젯 생성 시 State Object 도 함께 생성됨
Stateful 위젯 생성하는데 비용이 많이 드는 이유가 State Object 때문
이러한 State Object 를 버리고 새로 만들기보단 그대로 유지한 채 최대한 재사용하며 상태의 변화에 따라 새롭게 생성된 Stateful 위젯으로 링크만 업데이트되는 전략

State Object 는 위젯이 Element Tree에 처음 연결될 때 한 번 생성되고,
Element가 제거(dispose)될 때 함께 메모리에서 해제된다.
쉽게 설명하자면 해당 위젯이 화면에서 완전히 제거될 때 메모리에서 정리되어 함께 사라진다.

위젯은 변하면 무조건 재생성함. 이 자체가 불변성
Stateful 위젯 역시 불변성으로 인해 재생성 해야하니 비용이 많이드는 State Object 은 Stateful 위젯에 포함하지 않고 Element tree 에 State Object 가 존재하는것
예측 가능한 UI 구조가 필요.
Widget 이 절대 변하지 않으니 데이터 전달로 인해서 발생하는 상태의 변화는 오직 Build 메소드를 통해서만 이루어짐
Element 트리의 최적화
기존 Element 를 유지한 채 링크를 업데이트하는 방식으로 Widget 만 새로 연결함으로 그 성능을 효율적으로 유지
위젯 비교 및 정보 확인의 편리성
한번 생성된 Widget 은 변하지 않으므로, 기존 Widget 과 새 Widget 을 비교해서 바뀐 부분만 다시 그릴 수 있음
const
컴파일 타임때 변수의 값을 결정하며, 이후 해당 값은 절대 변하지 않음
동일한 const 생성자는 컴파일 타임에 단 하나의 인스턴스만 생성되어 같은 객체 참조를 재사용
const Text('Hello') === const Text('Hello') // true
immutable 한 변수나 위젯에 사용하여 재사용 가능
현재는 flutter 에서 immutable 한 요소는 자동으로 컴파일 시점에 const 객체처럼 취급
final
런타임때 변수의 값을 결정하며, 이후 해당 값은 절대 변하지 않음
Widget 은 런타임에 사용되는 불변 객체로, 생성자는 필드를 final 로 초기화하는것이 적절
Widget 앞에 const 를 붙이면 런타임마다 새로 만들지 않고, 동일 인스턴스를 재사용하라는 의미
setState 로 인해 값이 변경되면, 해당 값을 사용하는 Widget 에 Dirty mark 를 해주어서 해당 부분만 리빌드 시 다시 생성
colorScheme
앱 전반에서 사용할 수 있도록 정리해둔 색상 팔레트
정밀한 색상 통제가 필요할 때 사용
// 아래 코드는 colorSchemeSeed 와 비슷하지만,
// 전체적인 조화에 맞춰 생성된 컬러에 대해
// 수정하거나 정교하게 통제 가능
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple)
colorSchemeSeed
하나의 seed 색상을 중심으로 자동으로 flutter 가 전체적인 조화에 맞춘 컬러를 계산해줌
디자인 지식이 부족해도 손쉽게 색상 테마를 구성할 수 있도록 해줌
.of(context) 는 현재 BuildContext 에서 가장 가까운 일치하는 위젯을 반환
State Object 개념 확실히 이해하기
// Widget
class MyWidget extends StatefulWidget{
...
}
// State Object (Widget 아님)
class _MyWidgetState extends State<MyWidget>{
...
}
initState
State Object 가 처음 생성될 때 딱 한번 실행되는 상태 초기화 시켜주는 메소드
@override
void initState() {
color = widget.passedColor;
super.initState();
}