Stateless Widget & Stateful Widget
- 플러터는 선언적으로 UI를 구성한다. : 위젯 내의 build 함수 내에서 상태를 반영하여 UI를 빌드
- f ( build ) : 앱의 상태 state를 반영하기 위해 사용자 인터페이스를 빌드
- state : ui를 새로 그리기 위해 필요한 데이터
State
State 즉 상태라는 것은 실행 중인 앱의 메모리에 존재하는 모든 것 혹은 UI 빌드하기 위한 데이터
해당 State의 변화를 감지하여 새로 화면을 다시 그릴지 아니면 State상태 변화에 관계 없는 위젯을 만들지 플러터 프로젝트 설계를 할 때 생각해봐야할 문제이다 .
1) Statefull
- 아무래도 사용자와 상호작용할 필요가 있음
- 사용자 입력, 데이터 입출력, 블루투스 연결 등 동적인 화면 구성에서 사용한다.
2) Stateless
- 아무런 상태를 가지지 않고 한 번만 그림
- 주로 정적인 화면 , 화면 로고 , 메뉴판 등의 화면 구성에서 사용한다.
1) Stateless Widget
- 위젯 내부에서 값이 변경되어도 다시 랜더링 할 수 없는 위젯
- setState 호출되어도 build함수가 실행되지 않음
- state를 가지지 않고 한 번 생성되면 그걸로 끝
2) Statefull Widget
- 위젯 내부에서 값이 변경되었을 때 마다 위젯 자체에서 다시 랜더링 실행할 수 있는 위젯
- setState 호출 시 build함수가 실행된다.
SplashScreen
- 스플래시 화면은 보통 어플이 기동할 때 나오는 화면으로 로딩중 등을 띄워서 본 앱이 준비되기 전까지 보여주는 화면
void main() {
//화면 전체에 SplashScreen위젯을 그릴 거니까 runApp의 매개변수로 넣어준다
runApp(const MaterialApp(
home: Scaffold(
body: SplashScreen(),
),
));
}
- 먼저 main에다가 runApp 매개변수로 MaterialApp을 넣어준다. 이로서 프로젝트 실행시 머티리얼 디자인 앱을 사용할 수 있는 기본 틀이 완성
- Scaffold를 사용해서 화면에 ui를 배치 시킬 수 있도록 정리
- 기본적으로 프로젝트 실행할 때는 아래의 구조를 이루고 있다.
1) main()
2) runApp()
3) MaterialApp()
4) Scaffold()
사용된 위젯 관련 설명
Container(
decoration: const BoxDecoration(
//color: Colors.orange,
color: Color(0xFFF99231),
),
1) Container
- 색상을 디자인 할 수 있어서 배경용으로 사용
- decoration 속성을 사용하고 BoxDecoration이라는 클래스의 color를 통해서 컨테이너 색상 변경이 가능
2) Color 클래스
- 이미 지정된 색상의 경우 Colors.색상이름 으로 사용
- 헥사 코드의 경우 아래 그림과 같지만 투명도 위치만 젤 앞에 위치해 있다.
Image.asset(
'assets/rupy.png',
width: 300,
height: 300,
),
3) Image.asset 생성자
- 앱에 저장된 asset 파일로 이미지를 그린다.
- pubspec.yaml에서 asset관련 설정을 활성화 해주고 프로젝트에 폴더를 만들어 이미지를 넣어준다.
- Image.asset 속성의 width , height 속성을 활용해서 크기 조절 가능
주의점
Row와 Colum
Row : 가로로 최대한의 크기를 차지 , 세로로 최소한의 크기를 차지
Column : 세로로 최대한의 크기를 차지 , 가로는 최소한의 크기를 차지
1) Column위젯만 있고 이미지에 크기를 지정하지 않았을 때
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
//color: Colors.orange,
color: Color(0xFFF99231),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/rupy.png',
// width: 300,
// height: 300,
),
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(
Colors.white
),
),
],
),
);
}
- 보통 Image위젯은 원본 크기를 유지하려고 한다.
- 해당 이미지의 경우 이미지의 크기가 지정되어 있지 않기 때문에 원본 이미지가 출력된 상태
Container에 대해서
1) Container에 크기를 지정하지 않을 때
- 하위 위젯의 크기를 제한하지 않음
- 하위 위젯의 원래 크기 그대로 나옴
2) Container의 크기를 지정할 때
- 크기를 명시적으로 지정한 경우 하위 위젯은 Container의 크기에 따라 제한이 걸림
- Container의 크기가 200*200일 때 하위 Image가 300*300이면 크기 제한 때문에 200*200으로 축소됨
참고로 Container는 크기 지정하지 않는 경우 가능한 가로, 세로 전부 꽉 차도록 랜더링 된다
2) 이미지 위젯에 크기를 명시적으로 정해줄 때
- 보통 이미지 위젯은 원본 크기를 유지하려고 한다. 명시적으로 지정한 경우 설정된 값에 따라 크기가 조절됨
- Image위젯을 감싸고 있는 Column의 경우 세로로 최대한 크게 차지하려고 하지만 가로는 최소한 차지하려고 한다. 이 때 하위 위젯인 Image가 200픽셀만 차지해버리니까 최소한으로 차지하려는 성질 때문에 Column이 차지하는 크기가 줄어들었다
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/rupy.png',
width: 300,
height: 300,
),
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(
Colors.white,
),
),
],
),
3) Row위젯을 사용하자
- 가로를 최대한 크게 차지하려는 Row위젯으로 감싸면 Column도 Row에 맞춰서 가로 비율이 꽉 채워짐
완성본
import 'package:flutter/material.dart';
class SplashScreen extends StatelessWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
//color: Colors.orange,
color: Color(0xFFF99231),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/rupy.png',
width: 300,
height: 300,
),
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(
Colors.white
),
),
],
),
],
),
);
}
}
참고
“이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.”
https://docs.flutter.dev/data-and-backend/state-mgmt
'프로그래밍 > 플러터' 카테고리의 다른 글
WebView & WebViewController (0) | 2024.02.24 |
---|---|
BuildContext란? (0) | 2024.02.23 |
플러터의 기본 위젯들 (0) | 2024.02.20 |
플러터 입문하기 (0) | 2024.02.19 |
Expand 위젯 에러 : RenderFlex children have non-zero flex but incoming height constraints are unbounded. (0) | 2024.02.19 |
하고 싶은 걸 하고 되고 싶은 사람이 되자!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!