화면 생성 흐름
- main() 함수에서 프로그램 시작. runApp() 함수를 통해 루트 위젯이 설정 됨
- MaterialApp 위젯을 통해 Material Design 스타일 적용 가능
- Scaffold 위젯을 사용하여 기본적인 레이아웃 구성
- 각각 위젯은 자신의 build 메소드를 통해 하위 위젯을 생성하고 배치
flutter 공식 문서 참조
https://docs.flutter.dev/ui/widgets
플러터에서 위젯트리는 앱의 UI를 구성하는 주요 개념이다. 위젯 트리란 앱의 모든 위젯이 계층적으로 구성된 구조를 나타낸다.
(1) 위젯 (Widgets)
(2) 부모와 자식 (Parents and Children)
- 위젯은 다른 위젯을 포함할 수 있다.
- 그에 따라 부모, 자식으로 나뉜다.
(3) 상태 (State)
- 일부 위젯은 변경 가능한 데이터를 가질 수 있다.
- 이 데이터를 상태라고 한다.
- 상태를 가진 위젯을 Stateful Widget 이라고 부른다.
쓰다보니 익숙해졌지만 처음에는 어떤 위젯들이 있고, 어떻게 사용되는지 아는게 진짜 중요하다. (GridView 라는게 있는지도 모르고 컬럼으로 하나씩 열 맞췄던 경험으로...)
GestureDetector
- 비주얼 적인 표현은 해주지 않지만
- 유저에 의해 만들어진 제스처 감지 ex) 유저가 컨테이너 위젯을 클릭시, GestureDetector 는 onTap() 을 호출. (tap, drag, scale 등 제스쳐 감지 가능)
- 제스처 콜백 가능
context
- 위젯트리에서 현재 위치를 나타내는 객체.
- 위젯의 부모와 위치에 대한 정보를 포함하며, 이를 통해 위젯 트리의 다른 부분에 액세스 할 수 있다.
- context는 buildContext 타입의 개체이며 Provider.of와 같 ㅊㅍ 은 메서드를 사용하여 위젯 트리에서 특정 타입의 위젯을 찾는 데에 사용한다.
child
- 부모 위젯이 자식위젯을 어떻게 렌더링해야하는지를 dart VM에게 알려주는 역할.
- 부모 위젯이 자식 위젯을 어디에, 어떻게 배치할지 결정하는데에 사용.
- Container, Center, Padding 등 단일 자식 위젯을 관리할 때 child를 쓴다.
children
- Row, Column, Stack 등, 여러 자식 위젯을 관리할 수 있는 위젯은 children 을 사용
Q. 모든 위젯이 child나 children을 가지나?
No. 모든 위젯들이 child 를 가지는 것은 아니다. 자식 위젯을 전혀 가지지 않는 위젯들도 있다. 예를 들면 Icon, Text 같은 위젯들은 그들 자체가 최종적으로 렌더링 되는 요소이기 때문에 자식을 가지지 않는다.
Container
- 원하는 UI를 담는 위젯
- 위젯의 배치나 크기, 여백 등 설정 가능
- 다른 위젯을 포함하고 일부 스타일링 특성을 Container 자체와 해당 하위 요소에 적용할 수 있다.
- 별도의 크기 설정이 없다면 child에 맞게 조정됨 (이게 진짜 중요하다)
- double.maxFinite = 위젯의 너비를 가능한 크게 만듦 (약 1.7976931348623…… 부동소수점 값이라서 double)
- 최대한 크게 만드는거지만 부모위젯의 크기를 초과할 경우 부모위젯에 맞춤
Scaffold
- 앱의 기본적인 레이아웃을 구성하는 위젯
- 다양한 프로퍼티를 가지고 있다.
- appBar
- body
- floatingActionButton
- persistentFooterButtons
Padding
- 자식 위젯 주변에 여백을 추가하는 위젯
- EdgeInsets 클래스의 인스턴스를 받는다.
- EdgeInsets.all(double value) : 네 방향 모두 동일한 여백 적용
- EdgeInsets.only({left, top, right, bottom}) : 특정 방향에만 여백 적용
- EdgeInsets.symmetric({vertical, horizontal}) : 수직 또는 수평 방향에 동일한 여백 적용
- EdgeInsets.fromLTRB : 각 방향에 다른 여백 적용
(참고) Padding 과 padding
- 플러터에서 Padding과 padding 은 서로 다른 개념이다.
- Padding
- padding
- ‘Edgeinsets 객체’
- 위젯의 패딩을 정의
setState
- 상태 관리를 위해 사용되는 함수.
- 상태를 변경하고, 그 변경사항을 반영하여 UI를 다시 빌드하는 역할을 함.
- setState의 기본 코드가 SetState(() {}); 이렇게 되어있는데, 여기서 첫번째에 있는 괄호는 입력값으로 받을 매개변수가 들어갈 자리인거고, 두번째에 있는 중괄호는 람다식(즉 함수 본문)이 들어갈 자리이다.
- setState 함수는 일반적으로 매개변수를 받지 않기 때문에 비어있는 경우가 많다.
Modal
- 사용자가 상호작용 할 수 있는 일종의 팝업 창
- Flutter에서는 showDialog나 showModalBottomSheet 같은 함수를 통해 구현 가능
- showDialog
- 일반적인 다이얼로그
- ex) 경고창, 확인 창 표시
- showModalBottomSheet
- 화면 하단에서 슬라이드로 올라오는 모달 시트
- ex) 메뉴, 추가 옵션 표시
Route
- Flutter 애플리케이션에서 화면 간 전환을 관리하는 개념
- 각 화면을 route 객체로 관리하며, 이를 navigation 위젯을 통해 전환 가능
- MaterialPageRoute
- Navigator.pop(context)
- Navigator.push ~
Appbar
- Image.asset : 이미지를 가져와 보여준다.
- Image.asset의 fit : 이미지를 어떻게 채워줄 것인지를 설정한다
- Boxfit.fill : 원본 비율을 무시한 채 꽉 채워준다.
- Boxfit.contain : 원본 비율이 유지되는 최대 크기. 이미지가 모두 보이게 한다.
- Boxfit.cover : 원본 비율이 유지되는 최대 크기. 긴 쪽이 짤린다.
- Boxfit.fitWidth : 원본 비율이 유지되는 가로 최대 길이, 높이가 짤릴 수 있다.
- Boxfit.fitHeight : 원본 비율이 유지되는 세로 최대 길이, 가로가 짤릴 수 있다.
- Boxfit.none : 크기를 조정하지 않으며 이미지가 짤릴 수 있다.
- title을 구성해준다.
PreferredSizeWidget
- 크기 조정이 가능한 위젯을 구현할 때 사용하는 클래스
- 높이나 가로길이를 조절해야하는 위젯을 만들 때 반드시 붙여줘야한다.
- appbar에 등록되는 위젯은 반드시 구현해줘야 한다.
- kToolbarHeight 는 flutter 툴바 높이를 의미하는 상수임 = 일반적으로 56.0
InkWell
- 사용자 이벤트를 처리할 수 있는 컨테이너
- 화면 요소에 사용자 이벤트 관련된 리스너가 없을 경우 사용한다.
MainAxisAlignment
- MainAxisAlignment
- 주축을 기준으로 요소를 정렬하는 속성
- 화면 최대 크기를 차지
- ex) Row면 가로 기준으로 요소 정렬, Column이면 세로 기준으로 요소 정렬.
- Row, Column 내부에 mainAxisAlignment 속성을 이용해 사용한다.
- 속성
- start, end, center
- spaceBetween : 위젯 사이의 간격이 동일하게 배치
- spaceEvenly : 동일 간격으로 배치하나, 끝 부분이 빈 공간으로 시작.
CrossAxisAlignment
- 횡축을 기준으로 요소를 정렬하는 속성
- 속성
- start, end, center
- strech : 위젯을 횡축 방향으로 모두 차지하도록 배치
Stack
- 여러 위젯을 겹치게 하는 레이아웃 요소
- 자식 위젯들을 상자의 가장자리에 상대적으로 배치
- 리스트 같은 형태이며, 첫 번째 자식이 가장 아래에 배치됨
- 꼭 ListView 내부에 써야할 필요는 없지만 ListView가 스크롤 기능이 있어서 같이 쓰임
ListView
- 안드로이드의 RecyclerView와 같은 기능을 하는 위젯
- 주요 속성
- itemBuilder : 목록의 각 항목이 어떻게 보여질지 정의. (각 항목의 모양과 데이터 지정)
- itemCount
DecorationImage
- BoxDecoration 또는 ShapeDecoration 과 같은 특정 데코레이션 클래스에서 사용할 수 있는 이미지를 정의하는데에 사용됨.
Q. image가 있는데 왜 DecorationImage를 써야되나?
- 플러터는 위젯으로 화면을 그린다.
- image는 위젯인데 Decoration은 위젯이 아니라 객체이다.
- DecorationImage는 Decoration 클래스의 일부로 위젯의 배경이나 테두리 등을 꾸미는 데에 사용한다. 위젯이 아니기 때문에 화면에 직접 그려지진 않지만 위젯 꾸미기를 돕는거다.
참고로 image 와 imageProvider도 다르다. image 를 셋팅하는 곳엔 image 위젯을 쓰고, imageProvider 로 되어있는거는 이미지 데이터를 관리하는 객체를 쓰면 된다.
Hex 코드로 Color 설정하는 법
0xff 뒤에 Hex 코드를 붙이면 된다.
color: Color(0xffFFFFFF)
Theme 적용
(출처 : https://dev-nam.tistory.com/10)
Flutter의 Theme는 앱 전체의 색상, 스타일, 그래픽 디자인 언어 등을 중앙에서 관리할 수 있게 해주는 기능입니다. Theme을 사용하면 앱 전체의 디자인 및 레이아웃을 일관되게 유지하면서 손쉽게 변경할 수 있습니다. 일반적으로 MaterialApp 위젯에서 theme 속성을 통해 앱 전체에 대한 테마를 많이 설정하고 있습니다.
primary: Colors.orangeAccent,
secondary: Colors.greenAccent,
tertiary: Colors.blueAccent),
ThemeData에서 대표적으로 설정 가능한 유형
textTheme: 전체적인 텍스트 스타일 설정. (ex. 제목, 부제목, 본문 텍스트 등). 이걸 쓰면 앱 전체에 동일한 폰트 적용이 쉽다.
buttonTheme: 버튼의 기본 스타일 및 모양 설정
- elevatedButtonTheme
- outlinedButtonTheme
- textButtonTheme 등...
floatingActionButtonTheme: FAB의 배경색, 모양, 높이 등 설정
inputDecorationTheme: 입력 필드(TextField)의 외관, 모양, 경계 스타일 등 설정
iconTheme: 아이콘의 색상, 크기, 불투명도를 설정
tabBarTheme: 탭바의 색상, 지시자 크기 및 스타일 설정
scrollbarTheme: 스크롤바의 두께, 반경, 색상 등 설정
dividerTheme: 구분선의 색상, 공간, 두께 등 설정