상세 컨텐츠

본문 제목

Flutter 반응형 레이아웃 디자인과 고급 레이아웃 패턴

공부/Flutter

by micalcomanie 2025. 1. 1. 11:49

본문

728x90
반응형
SMALL

Flutter는 다양한 화면 크기와 장치에서 일관된 사용자 경험을 제공하기 위해 반응형 레이아웃 디자인을 지원합니다.
이 글에서는 반응형 레이아웃 구현 방법과 고급 레이아웃 패턴을 다뤄보겠습니다.


1. 반응형 레이아웃이란?

반응형 레이아웃(Responsive Layout)은 화면 크기, 방향, 비율에 따라 UI를 동적으로 조정하는 디자인 방식입니다. 모바일, 태블릿, 데스크탑 등 다양한 장치에서 최적화된 UI를 제공합니다.


2. 반응형 레이아웃 구현 방법

2.1 MediaQuery

MediaQuery는 화면 크기와 관련된 정보를 제공합니다.

import 'package:flutter/material.dart';

class ResponsiveExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    double screenWidth = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        title: Text('Responsive Layout'),
      ),
      body: Center(
        child: screenWidth > 600
            ? Text('Tablet or Desktop Layout')
            : Text('Mobile Layout'),
      ),
    );
  }
}

2.2 LayoutBuilder

LayoutBuilder는 부모 위젯의 제약 조건에 따라 다른 레이아웃을 렌더링합니다.

LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth > 600) {
      return Text('Large Screen Layout');
    } else {
      return Text('Small Screen Layout');
    }
  },
)

2.3 Flexible과 Expanded

FlexibleExpanded를 사용하여 위젯의 비율을 조정합니다.

Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(color: Colors.blue),
    ),
    Expanded(
      flex: 1,
      child: Container(color: Colors.green),
    ),
  ],
)

2.4 AspectRatio

AspectRatio는 위젯의 가로 세로 비율을 유지합니다.

AspectRatio(
  aspectRatio: 16 / 9,
  child: Container(color: Colors.amber),
)

2.5 OrientationBuilder

화면 방향(세로/가로)에 따라 다른 레이아웃을 제공합니다.

OrientationBuilder(
  builder: (context, orientation) {
    return orientation == Orientation.portrait
        ? Text('Portrait Layout')
        : Text('Landscape Layout');
  },
)

3. 고급 레이아웃 패턴

3.1 Grid Layout

GridView를 사용하여 정렬된 그리드 레이아웃을 만듭니다.

GridView.count(
  crossAxisCount: 3,
  children: List.generate(9, (index) {
    return Container(
      margin: EdgeInsets.all(4),
      color: Colors.blue,
      child: Center(child: Text('Item $index')),
    );
  }),
)

3.2 Slivers

Sliver는 스크롤 가능한 영역을 효율적으로 관리하는 데 사용됩니다.

CustomScrollView(
  slivers: [
    SliverAppBar(
      expandedHeight: 200.0,
      flexibleSpace: FlexibleSpaceBar(
        title: Text('Sliver Example'),
      ),
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Item #$index')),
        childCount: 20,
      ),
    ),
  ],
)

3.3 Responsive Design 패키지 활용

  • flutter_screenutil:
    • 다양한 화면 크기에서 UI 요소 크기를 자동으로 조정.
    import 'package:flutter_screenutil/flutter_screenutil.dart';
    
    ScreenUtil.init(context, designSize: Size(375, 812));
    Container(
      width: 100.w,
      height: 50.h,
    );
  • responsive_framework:
    • 장치 유형에 따라 레이아웃을 자동으로 조정.
    ResponsiveWrapper.builder(
      child,
      defaultScale: true,
      breakpoints: [
        ResponsiveBreakpoint.resize(480, name: MOBILE),
        ResponsiveBreakpoint.autoScale(800, name: TABLET),
        ResponsiveBreakpoint.autoScale(1200, name: DESKTOP),
      ],
    );

4. 실습: 반응형 대시보드

간단한 대시보드를 만들어 반응형 레이아웃을 구현합니다.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Responsive Dashboard')),
        body: LayoutBuilder(
          builder: (context, constraints) {
            if (constraints.maxWidth > 600) {
              return Row(
                children: [
                  Expanded(child: Sidebar()),
                  Expanded(flex: 3, child: Content()),
                ],
              );
            } else {
              return Content();
            }
          },
        ),
      ),
    );
  }
}

class Sidebar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      child: Center(child: Text('Sidebar')),
    );
  }
}

class Content extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
      child: Center(child: Text('Content')),
    );
  }
}

5. 결론

Flutter의 반응형 레이아웃과 고급 패턴을 활용하면 다양한 장치에서 유연한 UI를 구현할 수 있습니다.
이 글에서 다룬 기법과 패턴을 조합하여 사용자 친화적인 앱을 만들어 보세요.

다음 글에서는 Sliver와 CustomScrollView를 심화적으로 다룰 예정입니다.


참고 자료

728x90
반응형
LIST

관련글 더보기