공부한 책
해당 책의 챕터8의 내용이다.
비유를 들자면 생물과 비생물의 차이 느낌이다. 숨을 쉬느냐 안 쉬느냐?
stateless는 한 번 화면에 그려지면 그대로 끝이다. 그래서 코드 상, 클래스 안에 변수를 선언할 수 없고, final을 통한 상수 선언만 가능하다.
컴파일 과정에서 에러가 발생하는데, 아마 화면 변화를 시도하는 미련한 행동을 애초에 막아놓기 위해 위젯을 상수로만 구성하도록 컴파일 과정에서 막아놓은 듯 하다. 런타임 상에서의 에러, 즉 변동이 가능할 줄 알고 실행해 보니 화면 변동이 없는 불상사...를 막기 위함이 아닐까!
그렇다면 다 stateful로만 구성하면 되는 것 아닌가? 유저와의 동적 상호작용이 중요한 시대에 stateless라는 이상한 애는 왜 만들어졌을까?
이 이유는 stateful과 stateless의 동작 원리를 통해 이해해 볼 수 있다.
위젯 => 빌더가 만든다!
stateless 위젯의 빌더가 실행된 뒤, 차후의 런타임에서 해당 위젯 내부의 변수가 바뀌었다고 해보자. 그런 경우에 화면은 변할 수가 없다. 왜냐? 빌더가 이미 실행되어 버렸고, 변수가 바뀌어봤자 빌더가 움직여주질 않으면 소용이 없다.
바로 setState() 메소드를 통해 가능하다. 변수 변경을 화면 변경, 즉 빌더에 명확히 전달하기 위해서는 무조건
setState() {안에 해당 구문들을 써줘야 한다!}
뭐 이런식으로 화면 그릴 때 핵심이 되는 변수를 바꿔주는 거임!!
빌더가 실행되면 최상위 위젯부터 맨 밑의 위젯까지 차례대로 다 실행이 된다. 그런데 난 최하단에 위치한 Text()위젯에 표시되는 거 하나만 바꾸고 싶다면...?
만약 모든 위젯이 stateful 위젯에만 들어있다면, 작은 내용 하나 바꿔 화면을 변동하고 싶을 때도 처음부터 다 그려야 하므로 느리고 비효율적일 것이다.
cf) 빌더에 인자로 들어가는 build(BuildContext context) 항상 궁금했을 텐데 뭘까? 여기서 좀 중요하다! 짚고 넘어가자.
context는 문맥 => 전후사정 =>내가 어디쯤 있나?하는 자기 인식! 같은 거임. 그렇다면 build context는? build를 어디서부터 해야 하나, 얼마나 build해왔나 하는 기록? 같은 거임. 내가 어디서부터 시작해야 하고 어디까지 해야할지가 담겨있다고 보면 됨.
stateful은 stateful만의 context 인자가 따로 있잖슴. 그러니깐 상위의 stateless와 구분해서 딱 필요한 만큼만 re-build할 수 있는 것이지!!
이미지 비율이 필요한 경우가 많다. 이에 유용한 위젯이다. child에 보통 이미지 위젯을 넣고,
aspectRatio 파라미터에 비율을 넣는다. (가로 / 세로 )
Padding(
padding: const EdgeInsets.all(16),
child: AspectRatio(
aspectRatio: 5/3,
child: Image.asset(
selectedPic[selectedId],
fit: BoxFit.cover,
),
),
);
추가로 위 코드 말미에 fit: BoxFit.cover도 자주 쓰이는 코드다.
1번 : 원본. 가로세로 비율 변화 없음(contain)
2번 : 지정한 영역을 꽉 채운다. 비율 변경됨. 가장 많이 사용하는 옵션 중의 하나(fill)
3번 : 너비에 맞게 확대 또는 축소. 수평으로 크기 때문에 위아래 여백 발생(fitWidth)
4번 : 높이에 맞게 확대 또는 축소. 수평으로 크기 때문에 수평 잘리는 영역 발생(fitHeight)
5번 : 지정한 영역을 꽉 채운다. 비율 유지. 3번 또는 4번을 상황에 맞게 선택(cover)
6번 : 원본 크기 유지. 원본으로부터 해당 영역 크기만큼 가운데를 출력. 기본 옵션(none)
출처: https://pythonkim.tistory.com/110 [파이쿵]
라고 한다. 이미지 넣을 일이 많을 것이므로 익혀 놓을 필요가 있겠다.
cf) 위에서 setState 얘기할 때, 변수를 바꿈으로써 화면을 변경한다고 했었는데 위 코드에 딱 예시가 나온다. selectedPic[selectedID] 리스트 안에 이미지의 내부 주소를 써놓고, 인덱스가 담겨있는 변수를 변경하면 이미지 변경 통한 화면 변경이 가능하겠쥬??
Container(
decoration: BoxDecoration(~~)
BoxDecoration 객체에 들어갈 네임드 파라미터 목록(사용해본 것만)
cf) 컨테이너의 특이한 성질, 크기 조정이 명시적으로 이루어지지 않은 상태에선, child가 없는 경우 가능한 한 화면에 꽉 차게/ child가 있으면 child 크기만큼 쪼그라드는 성질을 갖고 있다고 한다.
Stack위젯은 여러 위젯을 겹치려는 경우에 사용한다. Positioned 위젯은 여러 위젯이 겹쳐 있을 때 하위 위젯의 위치를 제어해야 하는 경우에 사용. 즉, 둘은 자주 같이 쓰임.
아래 코드를 참고해보자.
Stack의 children 안에 먼저 맨 밑에 들어갈 child가 들어가고, 그 다음 Positioned가 들어가 먼저 위치 조정을 해주고 child를 통해 실질적으로 맨 밑에 먼저 들어가 Container 바로 위에 올 요소를 언급해주는 것. Positioned는 Padding과 이용방법이 유사함.
cf) ClipOval이라는 위젯! => 하위 요소를 동그랗게 만들어주는 것 같다. 동그란 정도를 조절하려면 clipper라는 파라미터를 추가하고 객체를 넣어주면 된다. 자세한 건 검색...!!
아이폰 기반의 디자인..! 이 디자인 상에서 알림을 보내는 위젯이다.
일단 아래 코드를 살펴보자.
실제로 그래서 알림을 끌 때는 마치 화면 전환 후, 이전 화면으로 돌아갈때 쓰는 Pop을 그대로 써주면 된다.