본문 바로가기
플러터(Flutter) 레이아웃 강좌

MediaQuery를 이용한 반응형 레이아웃 설계하기

by everythingdev 2024. 9. 22.
반응형

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의 주요 속성들

  1. size: 화면의 크기
  2. orientation: 화면의 방향 (세로 또는 가로)
  3. devicePixelRatio: 물리적 픽셀과 논리적 픽셀의 비율
  4. textScaleFactor: 텍스트 크기 조정 비율
  5. platformBrightness: 시스템의 밝기 모드 (라이트 또는 다크)

고급 기법: LayoutBuilder 활용

  • MediaQuery와 함께 LayoutBuilder를 사용하면 더욱 세밀한 반응형 레이아웃을 구현할 수 있습니다.
LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    if (constraints.maxWidth > 600) {
      return WideLayout();
    } else {
      return NarrowLayout();
    }
  },
)
  • LayoutBuilder는 부모 위젯의 제약 조건에 따라 동적으로 레이아웃을 구성할 수 있게 해줍니다.

성능 최적화 팁

  1. MediaQuery.of(context)를 빌드 메서드 내에서 자주 호출하지 마세요. 대신 변수에 저장하여 재사용하세요.
  2. 불필요한 리빌드를 피하기 위해 const 생성자를 활용하세요.
  3. 큰 위젯 트리에서는 필요한 부분만 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(),
    );
  }
}
  • 이 예시에서는 화면 너비에 따라 뉴스 목록과 상세 페이지를 나란히 표시하거나 목록만 표시합니다.

주의사항 및 고려사항

  1. MediaQuery는 BuildContext를 통해 접근하므로, 항상 올바른 컨텍스트를 사용해야 합니다.
  2. 화면 회전이나 크기 변경 시 MediaQuery 값이 변경될 수 있으므로, StatefulWidget을 사용하여 적절히 대응해야 합니다.
  3. 테스트 시 다양한 디바이스와 화면 크기에서 레이아웃을 확인해야 합니다.

맺음말

  • Flutter의 MediaQuery는 반응형 레이아웃 구현을 위한 강력한 도구입니다.
  • 화면 크기, 방향, 해상도 등 다양한 요소를 고려하여 사용자 경험을 최적화할 수 있습니다.
  • 이를 효과적으로 활용하면 다양한 디바이스에서 일관된 사용자 경험을 제공하는 앱을 개발할 수 있습니다.
  • 다음 포스팅에서는 LayoutBuilder 강좌로 돌아오도록 하겠습니다.
반응형