[Flutter] Widget_studying

Jiwon·2022년 11월 14일
0

단축키

- Shift+F10: 실행
- Ctrl+ Space: 자동완성
- Alt+ 4: 콘솔창 
- 전체 선택 후 Ctrl+ Alt+ L: 코드 정리
- Alt+ Enter: 현재 위젯을 벗겨내거나 다른 위젯으로 감싸기

Flutter 공부 정리

- 스마트폰 앱은 크게 네이티브, 하이브리드, 크로스 플랫폼 방식으로 개발
• 네이티브:  안드로이드-자바 or 코틀린
			IOS-엑스코드로 개발, 개발언어는 스위프트 or 오브젝티브C
• 하이브리드: 웹 기술로 앱 화면을 만든 후 네이티브 기술로 감싸서 앱 형태로 포장
• 크로스 플랫폼: 한 번 구현하여 안드로이드와 IOS 등 각 플랫폼용 앱 만듦

- 플러터는 한 번 코딩으로 여러 플랫폼용 앱을 만드는 크로스 플랫폼 개발 프레임워크
- 위젯과 상태 갱신 두가지는 플러터 개발자가 신경 써야 하는 두가지 핵심 개념!
- 플러터는 상속보다 조합을 우선시하며 이를 이용해 고유한 위젯을 만듦
- 위젯은 다양한 생명주기 메서드와 객체 멤버를 포함한다. 가장 중요한 메서는 build()인데 모든 플러터 위젯은 build() 메서드를 반드시 정의해야 함
- 플러터는 기존에 빌드하고 그렸던 위젯을 필요한 곳에 재사용 가능
- 래스터라징을 끝으로 위젯이 화면에 그려짐
	○ 플러터는 리액티브다.
	○ 모든 것은 위젯이다.
	○ State 객체는 오래 살아남으며 종종 재사용된다.
	○ 위젯의 제약은 부모가 서술한다.

• 머티리얼 디자인(구글에서 제공하는 디자인 가이드)
- Import 'package:flutter/material.dart';

• 쿠퍼티노 디자인(애플에서 제공하는 디자인 가이드)
- Import 'package:flutter/cupertino.dart'
- 쿠퍼티노 디자인에서는 AppBar 대신 CupertinoNavigationBar를 사용하며 CupertinoSwitch, CupertinoButton, CupertinoAlertDialog, CupertinoPicker 등을 사용함
- 체크박스나 라디오 버튼이 따로 없고 스위치만 사용

- 패키지 네임에는 컴퍼니 도메인과 앱 이름의 조합으로 패키지명이 결정됨
- 패키지명은 앱을 나타내는 고유한 값으로 구글 플레이 또는 앱스토어에 업로드할 때 기존에 중복되는 값이 있으면 업로드 되지 않음
• 자바, 오브젝트-C

- 앱을 실행 가능한 형태로 만드는 동작을 빌드라고 함
- 안드로이드 폰에서 플러터 앱을 실행하려면 개발자 모드를 활성화 해야함 

Import 'package:flutter/material.dart';

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

Class MyApp extends StatelessWidget{ //StatefulWidget(상태변화가 있는 위젯) ->상태변화가 없는 위젯
Const MyApp({super.key});

- Statelesswidget 클래스: build() 메서드를 가지고 있는데 
위젯을 생성할 때 호출되는데 실제로 화면에 그릴 위젯을 작성해 반환함
	○ 언제 파괴되어도 괜찮은 위젯으로 이 위젯은 어떠한 정보를 저장하지 않으므로 위젯이 사라져도 별일이 없음/ 상태가 없는 위젯은 새로운 정보에 반응함
	○ 상태가 있는 위젯(StatefulWidget)과 상태가 없는 위젯(StatelessWidget)으로 나뉨

- Snackbar 사용을 위해서는 home에서 scaffold 이용
• 중앙으로 이동시 alignment:Alignment.center, 사용

- Const: 상수 활용	

- 플러터에서는 화면을 그리는 모든 디자인 요소를 위젯이라고 함

- MetrialApp() 클래스:  
title(제목), theme(테마), home 세 가지 이름이 있는 인수를 설정

--> 이름 있는 인수는 인수 앞에 인수명을 씀

- MyHomePage 클래스의 생성자는 key와 title 프로퍼티를 옵션으로 받아서 
super 키워드로 부모 클래스의 생성자에 key르르 전달

- State 클래스: 주로 상태를 저장할 변수들과 그 변수를 조작할 메서드를 작성

- Scaffold 클래스: 머티리얼 디자인 앱을 만들 때 뼈대가 되는 위젯

- Myapp->MaterialApp->Scaffold->appBar->body 순서로 좁아짐

- FloatingActionButton 클래스

- 널 안전성
• 널 안전성을 도입하면 해당 변수 타입이 널을 허용하는지 아닌지를 정확하게 대입해야 함
• 널을 대입하기 위해 타입 옆에 ? 를 붙이면 됨
-> int? i = null; 
• 결론적으로 널 안전성이 도입되면 String과 String?는 다른 타입으로 취급
• 늦은 초기화 시 -> late 키워드를 선언 앞에 붙임
• 널일 수 있는 값을 처리하는 방법 -> ?? 를 사용하면 널을 허용하지 않는 타입으로 변환
*int value = nullableValue ?? 0
• 널을 허용하는 타입을 매개변수로 사용하는 메서드가 있다면 명확히 타입을 정의해 줘야 함-> str=null
• 널이 아닐 때만 참조하도록 하는 ?. 활용 방법

- 코드 정렬 기능을 사용하려면 모든 프로퍼티의 마지막에 콤마를 찍는 것이 습관화되어 있는 것이 좋음

Flutter 본격 시작

import'package:flutter/material.dart';

voidmain(){
runApp(constMyApp());
}

• stless 입력 후 Myapp 클래스 입력
• Stful 입력 후 State 클래스 입력

위젯 종류

- 위젯은 앱 뷰의 모든 정보를 정의한다.
- 참고로 앱을 만드려면 레이아웃, 스타일, 애니메이션 등 다양한 기능이 필요하므로 보이는 것보다 위젯이 아주 많음
- 레이아웃(Row, Scaffold, Stack 등)/ 구조(Button, Toast, MenuDrawer 등)/ 스타일(TextStyle, Color 등)/ 애니메이션(FadeInPhoto, Transform 등)/ 위치와 정렬(Center, Padding 등)

-MatrialApp(): 커스터마이징 시 사용
-Scaffold(): 상중하로 나눠줌
• appBar: 상단
• Body: 중단
• bottomNavigationBar: 하단

-AppBar() 디자인
• Title: 왼쪽제목
• Leading: 왼쪽에 넣을 아이콘
• Actions: [우측아이콘들]

-Text(): 글자를 표시하는 위젯
• Text()는 style: 안에 스타일 넣을 수 있음
style: TextStyle()
color: 색주는 법 1) Colors.칼라명
2) Color(0xffaaaaaa)

*fontsize
*letterSpacing
*fontWeight

-Icon(): 아이콘을 표시하는 위젯
• Color
• Size
• 머티리얼 디자인용 기본 아이콘들은 Icons 클래스에 상수로 미리 정의됨

-Image(): 이미지를 표시하는 위젯
• pubspec에 경로 지정
assets:
-assets/
후에 Image.asset('assets/파일경로')
수정한 후에는 터미널에서 flutter pub get 명령을 실행하여 프로젝트에서 이미지 파일에 접근할 수 있게 해야 함
• Network() 메서드에 이미지 파일의 URL 입력 시 네트워크에 있는 이미지 표시

-Progress(): 로딩 중이거나 오래 걸리는 작업 시 사용자에게 진행 중임을 보여주는 용도로 사용하는 위젯
• CircularProgressIndicator(): 둥근 형태
• LinearProgressIndicator(): 선 형태

-CircleAvatar(): 프로필 화면 등에 많이 사용되는 원형 위젯
• Child 프로퍼티에 정의한 위젯을 원형으로 만들어줌
• 네트워크상에 존재하는 이미지를 표시한다면 backgroundImage 프로퍼티에 NetworkImage 클래스의 인스턴스를 지정해야 가능

-Container(): 네모박스 넣을 시 사용
• Width: double.infinity -> 가로로 무한히
• height
• color(flutter의 사이즈 단위는 LP/50LP=1.2cm)
• Margin(바깥쪽여백): EdgeInsets. all(20) / fromLTRB(0,0,0,0) -> 박스에 여백주기
• Padding(안쪽여백): EdgeInsets.all(20)- 네 방향 모두 같은 값을 지정 / only() 함수는 상하좌우 중에서 원하는 방향에만 값을 지정
앞에 const를 붙이면 컴파일 타임에 상수로 정의되어 재사용 가능
• Decoration: BoxDecoration() -> 박스에 테두리주기
나머지 박스 스타일들은 decoration: 안에 넣어야함
Border: Border.all(color: Colors.black)

-SizedBox(): 높이 조절 시 사용
• 위젯 중에는 크기에 관련된 프로퍼티가 없는 위젯이 많은데 그러한 위젯을 특정 크기로 만들 때 사용
• Width, height, child만 필요한 박스 사용 시

-Row(): 여러 위젯 가로로 배치
• Row( children:[리스트형태로 여러 위젯 나열] )
• Row() 의 mainAxis는 가로정렬 -> max(최대크기), min(최소크기)
• Row() 의 crossAxis는 세로정렬 -> center, start(왼쪽정렬), end(오른쪽정렬), spaceevenly, spacebetween, spacearound

-Column(): 여러 위젯 세로로 배치
• Column( children:[리스트형태로 여러 위젯 나열] )
• Column() 의 mainAxis는 세로정렬
• Column() 의 crossAxis는 가로정렬
• 기본적으로 표시할 위젯의 크기만큼 가로 길이를 가짐

-Opacity(): 위젯이 공간은 차지하고 있으나 투명해져서 보이지 않게 됨
• Opacity 값이 0이면 완전 투명, 1이면 완전 불투명

-Stack(): children에 나열한 여러 위젯을 순서대로 겹치게 함
• Ex) 사진위에 글자 표현, 화면 위에 로딩 표시
• Children 프로퍼티에 정의한 리스트에 먼저 작성한 위젯이 가장 아래쪽에 위치하고, 나중에 작성한 위젯이 위쪽에 위치함

-Center(): 내 자식 위젯의 기준점을 중앙으로 설정해줌--> 위젯 안에 위젯 넣기 가능
• 위젯 ( child: 위젯() ): 자식 상속 파라미터

-Align(): 박스 위치 정렬(자식 위젯의 정렬 방향을 지정)
• Align(alignment: Alignment.위치)

-TextButton(): 평평한 형태의 버튼
• 버튼엔 반드시 child: 와 onPressed/onTapped/onHorizontalDrag 등: 넣어야 잘보임
• Button()는 style: 안에 스타일 넣을 수 있음
*style: ButtonStyle()
• 버튼 위젯들은 모두 onPressed 프로퍼티에 버튼이 클릭되었을 때 실행될 함수를 반드시 정의해줘야 버튼이 활성화되며 클릭이 가능1
• Null 지정 시 버튼이 클릭되지 않는 비활성화 상태가 됨

-IconButton(): 아이콘을 표시하는 버튼
• Icon:Icon(Icons.아이콘이름)
onPressed: (){}

-ElevatedButton(): 입체감을 가지는 일반적인 버튼

-FloatingActionButton(): 입체감 있는 둥근 버튼(아이콘 표시하는 데 사용)

-Flexible()
• 박스 폭을 50%로 설정하려면?
-> Flexible()로 감싸야함

-Expanded(): 자식 위젯의 크기를 최대한으로 확장시켜주는 위젯
• Row() 안에서 박스 하나만 꽉 채우고 싶으면 Expanded() 사용
• Flex:1 가진 Flexible 박스랑 동일
• 여러 위젯에 동시에 적용하면 flex 프로퍼티에 정숫값을 지정하여 비율을 정할 수 있으며 기본값은 1

=> 박스폭을 %로 주고 싶으면 Flexible/박스 하나 넓게 채우려면 Expanded

-ListView(): 많은 항목을 세로로 나열할 때 스크롤바 생성
• 스크롤 위치 감시 가능
• 메모리 절약기능
• 리스트 아이템을 쉽게 작성할 수 있는 ListTitle 위젯 사용하면 편리
ListTitle 위젯은 leading, title, trailing 프로퍼티가 각각 왼쪽, 중앙, 오른쪽 위치를 담당해 자유롭게 아이콘이나 글자 배치 가능, onTap 프로퍼티에는 리스트의 항목을 탭했을 때 실행해야 하는 동작을 정의한 함수를 작성
• 다른 스크롤 객체 안에 ListView 위젯을 넣을 땐 shrinkWrap과 physics 프로퍼티를 정의함

-SingleChildScrollView(): 많은 항목을 세로로 나열할 때 스크롤바 생성

-ListBody(): 스크롤 기능 영역이 가로로 꽉 차기 때문에 사용자가 스크롤하기 더 수월

-GridView(): 열 수를 지정하여 그리드 형태로 표시
• GridView.count() 생성자는 간단하게 그리드 작성
• crossAxisCount 프로퍼티에 열 수를 지정

-PageView(): 여러 페이지를 좌우로 슬라이드하여 넘길 수 있도록 해줌
• Tab과 연동하여 사용하지 않으면 좌우로 슬라이드가 가능한지 사용자가 모를 수 있어서 단독으로는 사용X

-AppBar, TabBar, Tab, TabBarView(): PageView()와 유사하지만 페이지와 탭이 연동되는 화면 구성 가능

-Carousel_slider(): 자동 스크롤 지원 기능

-BottomNavigationBar(): 하단에 2~5개의 탭 메뉴를 구성할 수 있는 위젯으로 각 탭을 클릭하여 화면을 전환할 때 사용
• Scaffold의 프로퍼티 중에서 정의
• 탭을 정의하고
Icon과 label 프로퍼티를 정의하여 구현
(BottonNavigationBarItem을 통해)

-Card(): 카드 형태의 모양을 제공하는 위젯
• 기본적으로 크기가 0이므로 자식 위젯의 크기에 따라 크기가 결정
• Shape 프로퍼티는 카드 모양을 변경하는 방법 제공
• Elevation 프로퍼티를 지정하여 그림자의 깊이를 조정

입력용 위젯

-TextField(): 글자를 입력받는 위젯
• InputDecoration 클래스와 함께 사용하면 힌트 메시지나 외곽선 등의 꾸밈 효과를 추가 가능-> labelText 프로퍼티를 활용하여 힌트 표현
• TextEditingController: 입력값 출력하기-> 인스턴스를 통해 TextField 위젯에 작성된 값을 얻을 수 있음
• Form, TextFormField: 폼의 입력값 검증하기

-CheckBox()와 Switch(): 설정 화면에 많이 사용되는 체크박스, 라디오 버튼, 스위치 표현
• 상태를 나타내는 불리언 타입의 변수 필요하고 value 프로퍼티에 설정
• onChanged 이벤트는 체크값이 변할 때마다 발생하는데 여기서 변경된 값이 불리언 value 인수로 넘어오며 setState() 함수를 통해 value 프로퍼티에 지정한 변숫값을 변경하며 UI를 다시 그림
• 상태를 나타내는 변수가 등장하므로 StatefulWidget

-Radio와 RadioListTile(): 선택 그룹 중 하나를 선택할 때 사용하는 위젯
• 그룹이 되는 항목을 열거형(enum)으로 정의하고 groupValue 프로퍼티에 열거형으로 정의한 Gender 타입의 변수를 지정하고 onChanged 이벤트에서 변경된 값을 반영

-DropDownButton(): 여러 아이템 중 하나를 고를 수 있는 콤보박스 형태의 위젯
• Value 프로퍼티에 표시할 값을 지정
• Map() 함수를 사용하여 _valueList 리스트의 문자열 3개를 DropdownMenuItem 인스턴스 3개로 변환-> map() 함수를 사용하여 값 리스트를 위젯 리스트로 변환하는 코드 자주 사용

다이얼로그 위젯

-AlertDialog(): 머티리얼 디자인의 유저 확인용 다이얼로그
• AlertDialog를 표시하려면 showDialog() 함수의 builder 프로퍼티에 AlertDialog 클래스의 인스턴스를 반환하는 함수를 작성하면 됨
• Title, content, actions 영역을 정의

-DatePicker(): 날짜 선택 시 사용
• Future 타입은 then() 메서드를 사용해 결과를 받는 함수 작성 가능
• 날짜가 선택되면 _selectedTime 변수를 갱신하고 setState() 함수를 호출하여 표시

-TimePicker(): 시간 선택 시 사용
• showTimePicker() 함수를 호출하면 타임 피커를 표시
• 날짜가 선택되면 timeOfDay.hour, timeOfDay.minute 에서 시간과 분을 얻을 수 있음

-GestureDetector()와 InkWell(): 글자나 그림 같이 이벤트 프로퍼티가 없는 위젯에 이벤트를 적용하고 싶을 때 사용하는 위젯
• onTap 프로퍼티를 가지고 있어서 child 프로퍼티에 어떠한 위젯이 와도 클릭 이벤트 작성
• InWell은 클릭 시 물결 효과

애니메이션

-Hero(): 화면 전환 시 자연스럽게 연결되는 애니메이션
• 애니메이션 효과의 대상이 되는 양쪽 화면의 위젯을 Hero 위젯으로 감싸고 tag 프로퍼티를 반드시 동일하게 지정

-AnimatedContainer(): 한 화면 내에서 setState() 함수를 호출하여 화면을 새로 그릴 때 변경된 프로퍼티에 의해 애니메이션되도록 해줌
• Duration, curve 등의 애니메이션 관련 프로퍼티 존재

-SliverAppBar()와 SliverFillRemaining(): 화면 헤더를 동적으로 표현하는 위젯(헤더/내용영역)
• 헤더를 위로 스크롤하면 헤더 부분이 작아지면서 헤더 하단에 있던 정적인 내용만 보이는 AppBar 형태로 애니메이션됨 <- 이런 효과를 Sliver
• Pinned: 축소될 때 상단에 AppBar가 고정될지 사라질지 설정
• expandedHeight: 확대될 때의 최대 높이 지정
• flexibleSpace: 확대/축소되는 영역의 UI 작성

-SliverAppBar와 SliverList(): 동적인 ListView를 사용하여 Sliver 효과를 줄 때 사용

내비게이션

• 파일 하나에 모든 클래스 작성 가능(main.dart 파일)
• 파일을 분리할 경우에는 임포트하여 다른 파일에 있는 클래스 사용 가능
• 화면 전환하려면 Navigator 클래스의 push() 메서드 사용
-Navigator.push(
	Context,
	MaterialPageRoute(builder:(context)=> [이동할 페이지]),
);

-> 새로운 화면이 표시되어도 이전 화면은 메모리에 남게 됨
• Navigator.pop() 메서드로 현재 화면을 종료하고 이전 화면으로 돌아감
• 이전 화면으로 데이터 돌려주기-> Future 값을 반환받으려면 await 키워드를 메서드 실행 앞에 추가하고 async 키워드 추가
*어떤 일이 끝날 때까지 기다리면서 앱이 멈추지 않도록 하는 방식을 비동기 방식

• Routes를 활용한 내비게이션
-routes 프로퍼티에 Map 형태로(키-값 쌍으로) 문자열과 목적지 인스턴스를 작성
-routes:{
	'/first':(context)=>FirstPage(),
	'/second':(context)=>SecondPage(),
	},
);

}
}
-> / 기호는 페이지 구조를 /first/a/b 와 같은 형식으로 구조화하기 쉬워 사용

-pushNamed() 메서드를 사용하여 화면 내비게이션 실행

• StatefulWidget 클래스에는 build() 메서드 외에도 특정 타이밍에 실행되는 여러 메서드 존재(생명주기 메서드)
-initState(): 위젯이 생성될 때 호출
-dispose(): 위젯이 완전히 종료될 때 호출

커스텀 위젯 문법

• 위젯들 한 단어로 축약하려면
1) Class 작명
2) Return 옆에 축약할 레이아웃 넣기

• 변수, 함수 문법으로도 축약 가능
*변하지 않은 UI들만 변수 함수로 축약해도 상관없음
*var a= SizedBox(
	Child: Text('안녕'),
);

• 아무거나 다 커스텀 위젯화 불가능
재사용 많은 UI들 or 큰 페이지들만 커스텀 위젯화 가능

레이아웃 혼자서도 잘 짜는 방법

1) 예시디자인 준비
2) 네모로 보이는 건 네모 그리기
3) 바깥 네모부터 하나하나 위젯으로
4) 마무리 디자인

구현 순서

1) 뼈대 작성
2) BottonNavigationBar 위젯을 이용한 하단 탭 구성
3) AppBar 위젯 수정
4) 화면이 3개인 UI 작성
5) 상단 부분
6) 중단 부분
7) 하단 부분

• 전체 테마 변경: AppBar를 매번 수정하는 것보다 MaterialApp 클래스의 ThemeData 인스턴스를 수정하는 것이 더 편함
primarySwatch 프로퍼티 대신 primaryColor 프로퍼티를 지정하는 것이 AppBar의 색상이나 글자색을 수정하지 않아도 동일 효과
• Form, TextFormField, Globalkey를 사용하면 입력 폼의 에러를 간단히 검증할 수 있음
• TextFormField 위젯은 TextField 위젯의 기능에 추가로 오류 검증 로직을 추가할 수 있는 위젯
• TextFormField나 TextField 위젯에 입력된 값을 활용하려면 TextEditingController 클래스를 사용
• 복잡한 계산은 별도의 메서드로 분리하는 것이 가독성 및 코드 유지 보수 측면에서 좋음
• Timer 클래스를 사용하면 정해진 시간 간격으로 원하는 동작을 수행시킬 수 있음
• 숫자 형태의 문자열을 특정 자릿수로 만들고 0으로 채우려면 padLeft() 메서드 사용
• 다트에서 정수형 나누기 정수형은 double 타입
• 파이어베이스의 Firestore를 사용하면 쉽게 클라우드 DB를 사용할 수 있음
• Firestore는 실시간으로 데이터를 읽어올 수 있는 스트림을 제공함
• 스트림과 StreamBuilder를 사용하면 자동으로 실시간으로 DB의 내용을 표시할 수 있음
• 안드로이드에서 메서드 개수 제한을 피하려면 minSdkVersion을 21 이상으로 설정해야함

Firebase 활용

• 데이터베이스의 주요 기능은 추가, 읽기, 수정, 삭제, 가져오기
*기본코드준비-> 변수준비-> 전체UI작성-> 할일목록UI작성-> 전체 UI와 할일목록 UI결합-> 기능작성-> 기능과UI연결
• Pubspec.yaml 파일에 cloud_firestore:^1.0.0 입력
• 파이어베이스는 개인적인 서버 없이도 활용할 수 있는 다양한 서버 기능을 제공함
• Firestore는 NoSQL 데이터베이스의 일종으로 자료의 저장 단위는 문서이다.
문서는 컬렉션 안에 저장되며, 문서에는 키-값 형태로 다양한 형태의 자료를 저장가능

카카오 회원가입

• 카카오 SDK for developers 이용

0개의 댓글