본문 바로가기
flutter

Flutter[플러터] / MediaQuery 를 사용하여 반응형 UI 구현하기 (sizeOf, viewInsetsOf, textScalerOf, 미디어쿼리, 사이즈) MediaQuery (Flutter Widget of the Week)

by ch5c 2025. 5. 22.
반응형

MediaQuery class

미디어 쿼리가 주어진 데이터로 확인되는 하위 트리를 설정합니다.

예를 들어, 현재 뷰(예: 앱이 포함된 FlutterView ) 의 크기를 알아보려면 MediaQuery.sizeOf 를MediaQuery.sizeOf(context) 사용할 수 있습니다.

특정 메서드(예: MediaQuery.sizeOf 또는 MediaQuery.paddingOf )를 사용하여 현재 미디어를 쿼리 하면 해당 속성이 변경될 때마다 위젯이 자동으로 다시 빌드됩니다.

MediaQuery.of를 사용하여 쿼리하면 MediaQueryData 의 필드가 변경 될 때마다 (예: 사용자가 기기를 회전하는 경우) 위젯이 자동으로 재빌드됩니다. 따라서 전체 MediaQueryData 객체의 변경이 중요하지 않은 경우, 특정 메서드(예: MediaQuery.sizeOf  MediaQuery.paddingOf ) 를 사용하는 것이 더 효율적으로 재빌드됩니다.

범위 내에 MediaQuery 가 없으면 MediaQuery.of 및 MediaQuery.sizeOf 와 유사한 "...Of" 메서드가 예외를 발생시킵니다. 또는 MediaQuery.maybeOf  MediaQuery.maybeSizeOf 와 같은 "maybe-" 변형 메서드를 사용할 수 있습니다. 이 메서드는 범위 내에 MediaQuery 가 없을 때 예외를 발생시키는 대신 null을 반환합니다.

https://youtu.be/A3WrA4zAaPw

예제 코드

 


MediaQuery 는 화면 크기, 방향, 디바이스의 해상도, 접근성 설정(예: 텍스트 스케일 배율) 등 디바이스 및 뷰포트의 정보를 제공하는 위젯이다. 이 위젯은 반응형 UI 를 구현할 때 정말 빠져서는 안 되는 필수불가결한 위젯이라고 할 수 있겠다.

사용은 MediaQuery.of(context) 으로 하여 현재 콘텍스트에서 자신이 원하는 정보를 가져오면 된다. 한번 알아보자.

주요 속성
속성명 설명
size Size(width, height) 형식으로, 현재 화면의 너비와 높이를 나타냄
padding 시스템 UI(예: 상태바, 네비게이션 바)를 피하기 위해 필요한 패딩
viewInsets 키보드 등으로 인해 가려진 영역의 크기
devicePixelRatio 논리 픽셀 대비 실제 픽셀 비율 (예: 3.0이면 1px = 3 디바이스 픽셀)
orientation Orientation.portrait 또는 Orientation.landscape
textScaleFactor 사용자의 텍스트 크기 설정

 

자 일단은 가장 흔히 사용되는 것부터 알아보자. 바로 size 다. 이것이야 말로 반응형 UI 구현의 알파이자 오메가라고 할 수 있겠는데 flutter 3.0부터인가 암튼 최근에 들어서는 예제에 나와있는 것처럼 사용하지 않고 sizeOf 를 써서 사용한다.

MediaQuery.sizeOf(context).height // 높이(세로)
MediaQuery.sizeOf(context).width // 너비(가로)

이렇게 사용하게 되면 크기를 화면의 크기에 맞춰서 사용할 수가 있게 된다. 

비슷한 기능으로는 double.infinity 를 꼽을 수 있겠는데 그것이랑은 확연하게 다른 것이 MediaQuery 는 정말 딱 화면의 크기만큼만 사이즈를 잡아먹는 것이고 double.infinity 는 잡아먹을 수 있는 만큼 먹는 것이기 때문에 동작자체가 다르다고 할 수 있겠다.

암튼 이렇게 sizeOf 를 사용하여 크기를 가지고 오게 되면 화면의 사이즈를 가져오기 때문에 폰 기종이 바뀌든 뭐를 했든 간에 사이즈에 맞게 알아서 딱딱 변하는 위젯들을 볼 수 있을 것이다.

 

그다음 알아볼 것은 viewInsets 가 되겠다. 이건 쉽게 말해 키보드가 올라왔을 때 그 키보드창이 얼마만큼의 크기를 차이하고 있는지 알게 해 준다.

MediaQuery.of(context).viewInsets.bottom // (권장)
// 이것도 업데이트로 바뀌었기 때문에 마음에 드는 거 사용하면 됨
MediaQuery.viewInsetsOf(context).bottom

 

지금 이 영상에서 KEYBOARD 라고 되어 있는 부분이 키보드가 올라왔을 때 차지하고 있는 부분을 나타내고 있는 것이다.

그리고 안에서 viewInsets.bottom 값으로 몇을 잡아먹고 있는지도 확인이 가능해진다.

초반에 앱을 만들면서 젤 짜증 났던 것 중 하나가 이 키보드인데 이 놈의 키보드가 올라올 때마다 위젯들이 다 사이즈 오류가 나버려서 Scaffold 에 있는 resizeToAvoidBottomInset: false 를 먹이거나 스크롤 위젯을 먹이거나 둘 중에 하나의 작업은 무조건 해야 했었다. 하지만 viewInsets 가 있다면 다른 방법으로도 사이즈 오류를 해결할 수 있을 듯싶다.

 

세 번째로 알아볼 것은 TextScaler 인데 이건 사용자의 텍스트 크기 데이터를 가져올 수 있게 해 준다. 우리 폰에서 글꼴 크기를 바꿀 수 있다는 사실 알고 있는가? 사용자마다 기본 글꼴의 크기가 다르기 때문에 그를 고려해서 디자인을 해야 한다. 그러기 위해서는 텍스트의 크기를 알아야 하기 때문에 이 상수를 사용하게 된다.

MediaQuery.textScalerOf(context);

기본적으로는 이렇게 가져올 수 있고 특정 폰트 크기에 따른 실제 크기 계산을 하고 싶다면

final scaledFontSize = MediaQuery.textScalerOf(context).scale(16.0);

이렇게 가져와줄 수도 있다.

Text 위젯에서 textScaler 사용해줄 수도 있고

Text(
  '예시 텍스트',
  textScaler: TextScaler.linear(1.2), // 20% 증가
)

전체 위젯 트리에서 텍스트 스케일링을 적용해줄 수도 있다.

MediaQuery(
  data: MediaQuery.of(context).copyWith(
    textScaler: TextScaler.linear(1.2),
  ),
  child: YourWidget(),
)

 

이렇게 간단히 MediaQurey 에 대해서 알아보았다. 정말 정말 많이 사용하는 만큼 많이 알아둬야 좋은 위젯일고 생각한다. 도움이 되었길 바라며 마치겠다.

반응형

 

반응형