본문 바로가기
개발/플러터

[플러터] SafeArea 에 대해서

by 핸디(Handy) 2020. 5. 28.

들어가며

이번 글에서는 Flutter(이하 플러터)에서 가장 기본이 되는 위젯 "SafeArea"에 대해 살펴보고 사용법에 대해서 알아보도록 하겠습니다.

그런 후에 적용 예시를 통해 어떤 옵션이 있는지 또한 사용해야할 때의 유의점도 함께 살펴보겠습니다.

SafeArea

이름만 들어서는 안전한 영역?은 대체 뭐까라는 의문점을 들게 하는 위젯입니다.

하지만 매우 중요하고 의미있는 위젯이기도 한데요.

바로 Widget of the week 에서 첫번째로 설명하고 있는 위젯이기 때문입니다.

플러터 공식문서에서는 이 위젯을 이렇게 표현하고 있습니다.

A widget that insets its child by sufficient padding to avoid intrusions by the operating system.
- https://api.flutter.dev/flutter/widgets/SafeArea-class.html 중

번역해보자면 OS에 따른 침입(intrusions by the operating system)을 피하기 위해 충분한 패딩(sufficient padding)을 주는 위젯이라고 합니다.

여기서 OS에 따른 침입, 충분한 패딩이란 단어가 핵심 내용입니다.

또한 기능적으로는 Padding widget과 다를바가 없습니다.

한가지 차이점은 Padding widget은 강제적으로 padding을 넣는 반면,

SafeArea는 필요할 때만 넣는다는 것입니다.

 

OS에 따른 침입과 충분한 패딩

핸드폰의 UI의 경우 표준이 없습니다.

그래서 각각의 핸드폰 제조사마다 카메라, 버튼의 위치가 제각각이라 기종에 따라 내용이 가려지거나 사라지는 UI가 생기게 됩니다.

원래 이런 경우에 대응하여 각각의 os별로 여분의 패딩, 또는 마진을 주는 방식으로 직접 코딩을 했어야했습니다.

하지만 SafeArea를 이용한다면 더이상 os에 따른 추가작업을 안해줘도 되는 것입니다.

사용법

사용법은 간단합니다. 여타 위젯과 같이 사용하려는 위젯을 감싸는 형태로 구현이 됩니다.

하지만 주의할 점이 있는데요.  가끔 Scaffold 위젯 밖에 선언하는 것을 확인할 수 있습니다.

적절한 사용법은 body안에 선언해주는 것입니다.

기본 사용법

 

활용 예시

아래의 화면은 제가 개발하고 있는 프로젝트의 화면중 일부입니다.

한 화면은 3가지 경우에 따라 변경해봤습니다.

원본 , App bar 없는 경우 , SafeArea 적용

첫번째 화면의 경우 appBar, body, floatingActionButton(이하 fab), bottomNavigationBar(이하 bottomBar)로 이뤄져있습니다.

우리가 살펴보려는 SafeArea가 없는데도 이상이 없습니다. (그럼 왜 씀??)

그래서 우린 가운데에 있는 사진에 조금더 신경써야합니다.

특정 화면의 경우 appBar가 없는 경우가 있습니다.

한화면을 전체 사용하는 경우가 그렇습니다.

지금 방금 막 사진을 찍어봤는데요. 아래처럼 카메라의 preview가 필요한 화면에서 appBar가 필요할까요?

appBar는 통상적으로 전체 Height의 5~10%를 차지합니다.

데스크탑 대비 정보가 밀집되어 있는 모바일의 경우에는 불필요한 경우 appBar를 제거하여 콘텐츠를 강조하는 것이 일반적인 UI입니다.

그럼 다시 두번째 화면을 가볼까요?

화면 스크린샷 vs 유저의 시선에서 바라본 화면

두번째 화면은 appBar를 없애보았습니다.

코드

스크린샷과 유저의 시선으로 바라본 화면의 차이점이 느껴지시나요?

스크린샷(좌) 안드로이드(중앙) IOS(우)

이 화면에서 가장 중요한 중앙의 버튼의 텍스트가 가려지는 불편함이 생기게 되었습니다.

안드로이드는 아무런 셋팅을 하지 않으면 저렇게 반투명한 검은색띠에 가려지고 ios는 노치에 먹혀버립니다.

ㅇㅇㅇUI적으로 미완성되어 보이는 안좋은 상황이란 거죠.

만약 여기에서 SafeArea를 넣게되면 어떻게 될까요?

바로 아래와 같이 변경됩니다.

안드로이드(좌) IOS(우)

깔끔하게 정렬된 모습을 확인할 수 있습니다.

코드로는 아래와 같이 표현됩니다.

차이점은 body를 SafeArea로 깜싼 것밖에 차이가 없습니다.

다시 한번 SafeArea의 정의를 살펴보겠습니다.

OS에 따른 침입(intrusions by the operating system)을 피하기 위해 충분한 패딩(sufficient padding)를 주는 위젯이라고 했습니다.

실제 예시에서도 알수 있듯이 안드로이드, IOS는 둘다 상단여백에 대한 침입이 있었습니다. 그래서 SafeArea를 추가한 순간 충분한 패딩이 생기면서 UI적으로 완성되었습니다.

이제 활용예시를 살펴보았으니 옵션에 대해서도 살펴보겠습니다.

 

SafeArea 옵션

vscode가 알려주는 옵션리스트를 살펴보겠습니다.

생각보다 별거 없습니다. 그리고 일단 SafeArea만 선언하면 옵션을 추가해야하는 경우는 아직까진 없었습니다.

bottom, left, right, top

여기서 bottom, left, right, top은 os에 따른 침입을 허용하겠느냐에 대한 Bool값입니다.

위 코드처럼 top : false로 넣어버리면 다시 아래처럼 됩니다.

right와 left의 경우 엣지스크린이 적용된 화면의 경우에 여백을 줄 것같긴 한데.. 실제 디바이스가 없고 찾아본바로 결과가 없어서 우선 넘어가겠습니다.

아무튼 이런식으로 각각의 여백에 대한 허용여부를 결정합니다.

minimum

미니멈의 경우에 여백의 최소값을 지정하는 값입니다.

테스트로 40를 넣어봤는데요.

안드로이드(좌) IOS(우)

 

상하좌우의 여백이 모두 40으로 잡혀버리게 됩니다.

여기서 만약 최소값을 0으로 잡으면 어떻게 될까요?

공식문서를 살펴보면 미니멈 값과 안전마진중에 더 큰것으로 적용된다는 것입니다.

When a minimum padding is specified, the greater of the minimum padding or the safe area padding will be applied.
- https://api.flutter.dev/flutter/widgets/SafeArea-class.html 중

안드로이드(좌) IOS(우)

실제 테스트 결과 오히려 각각의 os별로 최소치가 적용되지는 것을 확인할 수 있습니다.

maintainBottomViewPadding

마지막 옵션입니다. 저도 이번글을 쓰기 위해서 이 옵션을 학습했는데요.

설명상에는 "온스크린 키보드가 표시된 경우 패딩이 소비되지 않고 장애물 아래에 유지될 수 있습니다." 라고 되어있습니다.

키보드로 인한 ui 움직임을 막는 옵션입니다.

댓글