이번 포스팅에서 알아볼 내용은 Flutter의 Widget입니다.
Flutter의 모든 위젯은 다루지는 않습니다.
하지만 필요한 위젯을 찾는 방법에 대해 학습하고 주로 사용하는 위젯을 알아볼 수 있습니다.
Flutter는 위젯으로 시작하고 위젯으로 끝나는 프레임워크이며 Flutter의 위젯은 웹에서의 HTML Element로 취급한다면 간단히 이해할 수 있습니다.
Widget??
Flutter는 위젯이 전부다라고 말해도 될 정도의 중요도를 가지고 있습니다.
화면에 표시되는 모든 요소가 위젯이며 눈에 보이지 않지만 화면을 구성하는 Layout도 위젯입니다.
위젯은 크게 두가지로 분류할 수 있습니다.
Stateful Widget
Stateles Widget
각각의 위젯을 살펴보겠습니다.
Stateful Widget
Flutter에서 StatefulWidget은 어떠한 상태 (State)를 갖고 있으며, 상태 값에 의해 화면에 움직임이나 변화를 표현할 때 사용합니다.
Stateful Widget은 사용자의 인터렉션에 의해 모양이나 형태를 변경할 때 사용합니다. ( 버튼, Http Response의 데이터 값 등)
Stateful Widget의 구현 방법은 StatefulWidget 객체를 상속받아 생성합니다.
Stateless Widget
Stateless Widget은 Stateful Widget과 반대로 어떠한 상태도 가지고 있지 않은 정적인 위젯입니다.
어떠한 상태 값도 가지고 있지 않으며 따라서 화면에서 어떠한 움직임이나 변화가 없습니다. ( 텍스트, 이미지 등 )
Stateless Widget 또한 StatelessWidget 객체를 상속받아 생성합니다.
Widget Tree?
하나의 Stateful Widget 혹은 하나의 Stateless Widget은 여러 위젯을 포함할 수 있습니다.
포함하며 이는 상위-하위 관계 혹은 부모-자식 관계를 가지게 됩니다.
이렇게 관계를 가지게 되면 이를 Tree 계층 구조로 표현할 수 있게 되며 관리 또한 가능합니다.
HTML이 웹 브라우저에 표시될 때 브라우저는 HTML 요소들을 DOM 트리로 생성하고 관리하는 것처럼 마찬가지로 Flutter는 모든 위젯을 Widget 트리로 생성하고 관리합니다.
부모 위젯은 Parent Widget 또는 Widget Container라고도 부릅니다.
BuildContext는 Widget Tree에서 위젯의 위치 정보를 제공합니다.
그렇기에 현재 위치에서 트리 상위에 위치한 위젯 정보를 얻을 수 있으며 이를 이용해 위젯이 속한 트리에서 가장 가까운 위젯에 속성이나 색상을 알아서 업데이트할 수 있습니다.
다양한 종류의 위젯 중에 주로 사용하는 위젯인 Scaffold, AppBar, Theme을 알아보겠습니다.
( doc : https://flutter-ko.dev/docs/reference/widgets )
WidgetsApp Widget
앱 전반의 테마, 내비게이터, 화면, 날짜 선택 UI, 알람 창 UI 등 대부분 앱에 필요한 기능을 추상화하여 제공하는 위젯인 WidgetsApp이 있습니다.
WidgetsApp Widget에 숙달된다면 UI를 비교적 쉽게 구현할 수 있습니다.
Material 디자인(안드로이드)을 제공하는 Material Design과 iOS 디자인을 제공하는 Cupertino Design이 있습니다.
(Material Design doc : https://docs.flutter.dev/development/ui/widgets/material)
(Cupertino Design doc : https://docs.flutter.dev/development/ui/widgets/cupertino )
Scaffold Widget
Scaffold Widget은 앱의 구조를 만드는 위젯입니다.
(HTML의 Div Element와 비슷한 역할이지만 같지는 않습니다.)
드로어(drawer): 한쪽 모서리에 미끄러지듯 등장하는 요소로 메뉴를 구현할 때 자주 사용합니다.
하단 시트(bottom sheet): 화면의 아래쪽에서 미끄러지듯 등장하는 요소로 iOS 앱에서 자주 사용합니다.
Scaffold에서 별도의 설정을 하지 않으면 Scaffold의 AppBar 앱 윗부분에 메뉴 버튼을 기본적으로 표시하며 이 버틀을 누르면 드로어가 열리게 됩니다.
( 메뉴를 갖지 않는 화면에서는 뒤로 가기 버튼이 자리 잡게 됩니다. )
Scaffold Property
const Scaffold({
Key key,
this.appBar,
this.body,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.floatingActionButtonAnimator,
this.persistentFooterButtons,
this.drawer,
this.endDrawer,
this.bottomNavigationBar,
this.bottomSheet,
this.backgroundColor,
this.resizeToAvoidBottomPadding = true,
this.primary = true,
}) : assert(primary != null), super(key: key);
모든 Property는 required가 아니어서 필수가 아닌 선택입니다.
따라서 Scaffold Widget은 다양한 스타일 또는 기능을 제공하며 자유롭게 원하는 기능만 사용할 수 있습니다.
AppBar Widget
AppBar의 기능을 제공하는 위젯입니다.
Scaffold의 appBar Property에 사용하며 화면 상단 위 특정 높이의 공간을 차지합니다.
드로어 인수가 not null이라면 자동으로 메뉴 버튼을 추가합니다.
뒤로 갈 수 있는 화면이라면 앱의 Navigator는 자동으로 뒤로 가기 버튼을 추가합니다.
AppBar는 다양한 위젯을 프로퍼티로 받으며 각각의 프로퍼티는 특정 위치에 배치됩니다.
메뉴 버튼과 뒤로가기 버튼을 처리하는 프로퍼티를 Leading Action이라고 부릅니다.
Leading과 automaticallyImplyLeading 프로퍼티를 설정할 수 있습니다.
PreferredSize Widget
AppBar 위젯은 명시적으로 너비와 높이를 커스텀할 수 있는 PrefferredSize 위젯을 상속받는 구현체입니다.
Scaffold.appBar의 프로퍼티는 AppBar의 크기를 알 수 있도록 PreferredSize 위젯을 요구합니다.
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ui.appBarHeight(context)),
child: AppBar()
),
);
PrefferredSize 위젯의 첫 인수는 Size 객체이고 두 번째 인수는 child 위젯을 갖습니다.
Theme Widget
Theme 위젯으로 자동으로 앱 전체에 스타일을 적용할 수 있습니다.
색상 관련된 프로퍼티
- brightness
- primarySwatch
- primaryColor
- accentColor
특정한 기능을 제어하는 프로퍼티
- canvasColor
- scaffoldBackgroundColor
- dividerColor
- cardColor
- buttonColor
- errorColor
이외에도 수많은 프로퍼티가 존재하지만 모두 사용하기 쉽지 않습니다.
flutter는 MaterialApp을 사용할 때 모든 프로퍼티에 기본값을 할당하여 개발자가 필요한 프로퍼티만 오버라이드 하도록 제공합니다.
MediaQuery And of Method
flutter에서는 논리적 픽셀(logical pixel) 한 가지 단위만 사용하여 대부분의 레이아웃 크기 문제를 해결해야 합니다.
flutter에서는 크기를 퍼센트로 사용할 수 없기 때문에 MediaQuery Widget을 이용해 화면 크기를 먼저 알아야 합니다.
BuildContext를 이용해 앱 어디서든 MediaQuery Widget을 사용할 수 있습니다.
final width = MediaQuery.of(context).size.width;
of 메서드는 위젯 트리에서 가장 가까운 MediaQuery 위젯의 reference를 반환합니다.
( of 메서드는 정적 메서드이기 때문에 MediaQuery 위젯의 인스턴스를 만들지 않고 직접 호출합니다. )
모든 of 메서드가 context를 인수로 받는 이유가 BuildContext는 트리에서 위젯의 위치 정보를 flutter에 제공합니다.
앱을 실행하는 물리적 디바이스의 정보를 얻거나 디바이스를 제어할 때 MediaQuery를 사용합니다.
- 현재 휴대폰이 세로 방향인지 가로 방향인지 확인할 경우
- 접근성과 관련해 애니메이션을 비활성화하고 색을 반전시킬 경우
- 사용자가 텍스트 크기를 확대했는지 확인할 경우
- 전체 앱에 Padding을 설정할 경우
ScreenAwareSize Method
Size.fromHeight는 정해진 높이와 무한대의 너비를 갖는 Size객체를 만드는 생성자로 ui.appBarHeight 메서드의 반환 값을 사용합니다.
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ui.appBarHeight(context)),
child: Container()
),
),
sreenAwareSize와 MediaQuery를 이용해 ui Util를 생성자 간편하게 사용할 수 있습니다.
final double toolbarHeight = 56.0;
double appBarHeight(BuildContext context) {
return screenAwareSize(toolbarHeight, context);
}
const double baseHeight = 650.0;
double screenAwareSize(double size, BuildContext context) {
double drawingHeight =
MediaQuery.of(context).size.height - MediaQuery.of(context).padding.top;
return size * drawingHeight / baseHeight;
}
BuilderContext로 MediaQuery 정보를 얻어 현재 위젯에 가장 가까운 MediaQuery를 가져와 크기 정보를 설정합니다.
자주 사용하는 UI 위젯은 다음 포스팅에서 알아보겠습니다.
'Frontend > Flutter &Dart' 카테고리의 다른 글
[Flutter] Flutter Widget의 생명주기를 알아보자! ( LifeCycle ) (0) | 2022.05.22 |
---|---|
[Flutter] 자주 사용하는 UI Widget을 알아보자! (0) | 2022.05.21 |
[Dart] Dart의 factory 키워드를 알아보자! (2) | 2022.05.18 |
[Flutter] Flutter 3.0 변경사항을 알아보자! (0) | 2022.05.14 |
[Dart] Dart 언어를 알아보자! ( Flutter ? ) (0) | 2022.04.27 |