TodayILearned/Flutter

2023.07.12 TIL -2주차

YJ_ILY 2023. 7. 12. 18:39

Flutter의 모든 위젯은 StatelessWidget StatefulWidget으로 나눠짐

StatelessWidget : 상태 변화가 없어 화면을 새로고침 할 필요가 없는 위젯

-화면이 한 번 그려지면 더이상 바뀌는 것이 없음 So, build함수가 1번만 호출됨

ex) 이용약관

-화면에 보이는 첫 번째 위젯은 일반적으로 MaterialApp 또는 CupertinoApp 위젯으로 시작

build라는 함수가 StatelessWidget이라는 클래스 안에 이미 있기 때문에 @Override해줌

StatefulWidget 상태 변화가 있어 화면을 새로고침 할 필요가 있는 위젯

-화면 안에 있는 내용이 변하는 위젯

-기본적으로 2개의 클래스로 구성

*StatefulWidget 위젯에서 setState()를 호출하면 build()함수가 다시 실행되면서 화면이 갱신됨!

_MyAppState은 MyApp상태를 가진 클래스로, 실질적인 내용이 들어가는 클래스

 

Navigation (화면 이동)

-Flutter에서는 각 화면을 라우트(Route)라고 부름

다음 페이지로 이동하기
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SecondPage()), // 이동하려는 페이지
);

현재 화면 종료
Navigator.pop(context); // 종료

앱을 시작할 때 MaterialApp으로 앱을 시작하고, home이라는 이름지정 매개변수(named parameter)에 첫 번째 페이지 위젯을 만들어 전달

*매개변수: 함수를 실행할 때 집어넣어주는 값들 

앱을 시작할 때  MaterialApp 으로 앱을 시작하고,  home 이라는  이름지정 매개변수(named parameter) 에 첫 번째 페이지 위젯을 만들어 전달

 

appBar의 영역

? actions에 아이콘이 여러개 들어갈때 왜 row로 묶어주지 않아도 될까..?

 

Body에서 레이아웃

Row와 Column을 이용해서 섹션별로 나누어서 큰 틀부터 작업을 하면 편함

* 여러 요소들을 겹치게 표현하기 위해서는 Stack 클래스를 사용해야 함

Row와 Column을 이용해서 섹션별로 나누어서 큰 틀부터 작업을 하면 편함

 

이미지를 추가할 때 ClipRRect로 감싸주면 이미지에 테두리를 넣어줄 수 있음

fit: BoxFit.cover는 이미지 비율 유지하면서 고정된 폭과 높이에 맞춰 이미지를 적절히 잘라서 보여줌

ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: Image.network(
           'image Url',
            width: 100,
            height: 100,
            fit: BoxFit.cover,
          ),
        ),

overflow발생 시

why? Column위젯의 폭이 설정되지 않았기 때문에 발생

So, Expanded 위젯을 통해 해결

1. overflow가 발생하는 Column을 wrap with widget으로 묶어줌

2. widget을 Expanded로 수정

-> 이렇게 하면 해당 위젯이 차지할 수 있는 공간을 최대로 차지하게 됨!

*Expanded 위젯: child 위젯이 차지할 수 있는 공간을 최대한 차지하도록 그 크기를 지정해주는 위젯

 

MainAxisAlignment주축 기준으로 어떻게 배치해줄 것인가

 

CrossAxixAlignment부축 기준으로 어떻게 배치해줄 것인가

SizedBox를 이용하면 위젯간의 간격을 조정할 수 있음Spacer는 빈 공간을 차지하는 위젯

SizedBox(width: 12),
Spacer()

모든 코드를 main.dart에 쓰면 코드가 길어지고 코드를 찾는 시간이 길어짐

-> 일반적으로 위젯들을 각각 다른 파일에 분리해두는 것이 좋음

*분리 후 import를 해줘서 Error를 해결해줌

 

대부분의 앱이 동일한 화면에 내용만 다른 피드를 스크롤하며 컨텐츠를 볼 수 있도록 구현되어 있음.

각 피드마다 매번 같은 코드를 반복해서 만들면 디자인이나 기능이 바뀔 때, 일일이 수정해야 해서 관리 어려움.

So, 반복되는 부분을 별도의 위젯으로 만들면 코드가 중복되는 문제를 해결 가능함.

반복되는 부분을 별도의 위젯으로 만들면 코드가 중복되는 문제를 해결

 

리팩토링(refectoring)

코드만 관리하기 쉽게 변경하는 과정

 

삼항연산자

조건 ? 반환값1 : 반환값 2

조건이 true인 경우 반환값 1로 , 조건이 false인 경우는 반환값2로 할당

isFavorite
    	? CupertinoIcons.heart_fill
    	: CupertinoIcons.heart,
    color: isFavorite ? Colors.pink : Colors.black,
    
 => isFavorite이 true이면 heart_fill하고, false이면 heart해라
 => isFavorite이 true이면 color를 pink로 하고, false이면 black으로 해라.

 

ListView 위젯(비효율적)

피드들을 리스트 형태로 만들어줄 때 사용

동일한 레이아웃에 다른 정보를 보여줄 때 사용시 유용함

*스크롤 가능한 column이라고 생각하면 편함 (스크롤 가능한 Column)

ListView(
	children: [
		Text("0"),
		Text("1"),
		Text("2"),
		...
	]
);

위의 ListView처럼 children을 직접 작성하는 것은 비효율적

ListView.builder()를 이용하면 적은 코드로 itemCount만큼 화면을 그릴 수 있음. (반복문같은 형태)

ListView.builder(
  itemCount: 100, // 전체 아이템 개수
  itemBuilder: (context, index) { // index는 0 부터 99까지 증가
		return Text("$index"); // 100번 실행
  }
),

 

상태 관리

서로 다른 페이지에서 변수를 공유하고, 변수의 값을 바꾸며 여러 페이지의 화면을 한꺼번에 갱신해주기 위해 적용