반응형
MediaQuery 강좌를 시작합니다.
- 플러터(Flutter) 시작을 위한 다트(Dart) 강좌는 19강 단위 테스트 강좌를 끝으로 종료가 되었습니다.
- 플러터(Flutter) 프로젝트 시작 전 디자인을 위한 레이아웃 강좌를 지속적으로 연재 중입니다.
Flutter MediaQuery를 이용한 반응형 레이아웃 구현하기
- 모바일 앱 개발에 있어 다양한 화면 크기와 해상도에 대응하는 반응형 레이아웃은 필수적입니다.
- Flutter에서는 MediaQuery를 활용하여 손쉽게 반응형 UI를 구현할 수 있습니다.
- 이번 포스팅에서는 MediaQuery의 개념부터 실제 적용 방법까지 상세히 알아보도록 하겠습니다.
MediaQuery란?
- MediaQuery는 Flutter에서 제공하는 위젯으로, 현재 디바이스의 크기, 방향, 텍스트 배율 등 다양한 미디어 정보를 제공합니다.
- 이를 통해 개발자는 앱의 레이아웃을 동적으로 조정할 수 있습니다.
MediaQuery 사용법
- MediaQuery를 사용하려면
BuildContext
를 통해 접근해야 합니다. 일반적으로 다음과 같이 사용합니다:
MediaQuery.of(context).size.width
MediaQuery.of(context).size.height
- 이를 통해 현재 화면의 너비와 높이를 얻을 수 있습니다.
반응형 레이아웃 구현 예시
1. 화면 크기에 따른 레이아웃 변경
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: screenWidth < 600
? MobileLayout()
: DesktopLayout(),
);
}
- 이 예시에서는 화면 너비가 600픽셀 미만일 경우 모바일 레이아웃을, 그 이상일 경우 데스크톱 레이아웃을 표시합니다.
2. 비율을 이용한 위젯 크기 조정
Container(
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.3,
color: Colors.blue,
)
- 이 컨테이너는 화면 너비의 80%, 높이의 30%를 차지하게 됩니다.
3. 방향에 따른 레이아웃 변경
Widget build(BuildContext context) {
final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
return Scaffold(
body: isPortrait
? PortraitLayout()
: LandscapeLayout(),
);
}
- 디바이스의 방향에 따라 다른 레이아웃을 표시할 수 있습니다.
- 위 예시코드
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MediaQuery 예시',
home: MediaQueryExample(),
);
}
}
class MediaQueryExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
// MediaQuery를 사용하여 화면 정보 가져오기
var mediaQuery = MediaQuery.of(context);
var screenSize = mediaQuery.size;
var orientation = mediaQuery.orientation;
return Scaffold(
appBar: AppBar(
title: Text('MediaQuery 예시'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'화면 너비: ${screenSize.width.toStringAsFixed(2)}',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Text(
'화면 높이: ${screenSize.height.toStringAsFixed(2)}',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Text(
'화면 방향: ${orientation == Orientation.portrait ? "세로" : "가로"}',
style: TextStyle(fontSize: 20),
),
],
),
),
);
}
}
MediaQuery의 주요 속성들
size
: 화면의 크기orientation
: 화면의 방향 (세로 또는 가로)devicePixelRatio
: 물리적 픽셀과 논리적 픽셀의 비율textScaleFactor
: 텍스트 크기 조정 비율platformBrightness
: 시스템의 밝기 모드 (라이트 또는 다크)
고급 기법: LayoutBuilder 활용
- MediaQuery와 함께 LayoutBuilder를 사용하면 더욱 세밀한 반응형 레이아웃을 구현할 수 있습니다.
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.maxWidth > 600) {
return WideLayout();
} else {
return NarrowLayout();
}
},
)
- LayoutBuilder는 부모 위젯의 제약 조건에 따라 동적으로 레이아웃을 구성할 수 있게 해줍니다.
성능 최적화 팁
MediaQuery.of(context)
를 빌드 메서드 내에서 자주 호출하지 마세요. 대신 변수에 저장하여 재사용하세요.- 불필요한 리빌드를 피하기 위해
const
생성자를 활용하세요. - 큰 위젯 트리에서는 필요한 부분만 MediaQuery를 사용하도록 분리하세요.
실제 프로젝트 적용 예시
- 다음은 MediaQuery를 활용한 간단한 뉴스 앱 레이아웃 예시입니다:
class NewsApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final isWideScreen = screenWidth > 600;
return Scaffold(
appBar: AppBar(title: Text('뉴스 앱')),
body: isWideScreen
? Row(
children: [
Expanded(child: NewsList()),
Expanded(child: NewsDetail()),
],
)
: NewsList(),
);
}
}
- 이 예시에서는 화면 너비에 따라 뉴스 목록과 상세 페이지를 나란히 표시하거나 목록만 표시합니다.
주의사항 및 고려사항
- MediaQuery는 BuildContext를 통해 접근하므로, 항상 올바른 컨텍스트를 사용해야 합니다.
- 화면 회전이나 크기 변경 시 MediaQuery 값이 변경될 수 있으므로, StatefulWidget을 사용하여 적절히 대응해야 합니다.
- 테스트 시 다양한 디바이스와 화면 크기에서 레이아웃을 확인해야 합니다.
맺음말
- Flutter의 MediaQuery는 반응형 레이아웃 구현을 위한 강력한 도구입니다.
- 화면 크기, 방향, 해상도 등 다양한 요소를 고려하여 사용자 경험을 최적화할 수 있습니다.
- 이를 효과적으로 활용하면 다양한 디바이스에서 일관된 사용자 경험을 제공하는 앱을 개발할 수 있습니다.
- 다음 포스팅에서는 LayoutBuilder 강좌로 돌아오도록 하겠습니다.
반응형
'플러터(Flutter) 레이아웃 강좌' 카테고리의 다른 글
LayoutBuilder로 동적 레이아웃 구현하기 (0) | 2024.09.26 |
---|---|
ConstrainedBox와 SizedBox 위젯 강좌 (0) | 2024.09.20 |
Wrap 위젯 가이드 (0) | 2024.09.19 |
AspectRatio와 FractionallySizedBox 위젯 완벽 가이드 (0) | 2024.09.10 |
Padding, Align, Center 위젯 활용하기 (0) | 2024.09.02 |