Advanced Responsive: Flutter용 완전한 Material Design 3 기반 반응형 시스템

발행: (2025년 12월 19일 오전 07:46 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

Flutter에서 반응형 레이아웃 만들기

Flutter에서 반응형 레이아웃은 종종 간단하게 시작하지만 금방 복잡해집니다.
몇 개의 MediaQuery 검사를 시작으로 브레이크포인트 로직을 추가하고, 스케일 팩터로 값을 곱합니다. 곧 위젯들이 조건부 렌더링과 하드코딩된 치수에 얽히게 됩니다.

advanced_responsive는 단순히 스케일링 유틸리티나 브레이크포인트 검사만 제공하는 것이 아니라 구조화된 Material Design 3에 맞춘 반응형 시스템을 제공하여 이를 해결하도록 설계되었습니다.

문제점

대부분의 Flutter 개발자는 다음과 같은 문제에 직면합니다:

// Different developers, different values
if (width  width;
// ... repeated in every widget
  • 중앙 집중식 진실 원천 없이 간격, 타이포그래피, 레이아웃 결정이 코드베이스 전역에 흩어져 있습니다.

기존 솔루션

솔루션초점
flutter_screenutilScaling utilities
responsive_frameworkBreakpoint checks
responsive_builderLayout switching

실제 반응형 디자인은 모두가 함께 작동해야 합니다.

advanced_responsive – 세 가지 기둥

기둥제공하는 것
일관성브레이크포인트와 간격에 대한 하나의 진실 원천
가독성의도를 명확히 하는 의미론적 API
유지보수성프로젝트가 성장함에 따라 쉽게 수정·확장 가능

패키지는 공식 MD3 브레이크포인트를 사용합니다:

디바이스 유형너비 범위그리드 열
Mobile(아래 참고 사항을 보세요)
Tablet(아래 참고 사항을 보세요)
Desktop(아래 참고 사항을 보세요)

**90 %**의 앱은 자동으로 적응하는 동일한 UI가 필요합니다.
**10 %**는 디바이스별로 완전히 다른 레이아웃이 필요합니다.

advanced_responsive두 가지 모두를 지원합니다.

적응형 UI (동일 UI, 다른 간격/타이포그래피)

ResponsiveBuilder(
  builder: (context, info) => Container(
    padding: EdgeInsets.all(info.spacing(ResponsiveSpacing.md)),
    child: Text(
      'Welcome',
      style: TextStyle(fontSize: info.responsiveFontSize(24)),
    ),
  ),
);

커스텀 UI (디바이스별 다른 레이아웃)

ResponsiveLayout(
  mobile: MobileView(),
  tablet: TabletView(),
  desktop: DesktopView(),
);
조건부 렌더링 예시
ResponsiveBuilder(
  builder: (context, info) {
    return Column(
      children: [
        Text(
          info.isDesktop ? 'Desktop Mode' : 'Mobile Mode',
          style: TextStyle(fontSize: info.responsiveFontSize(18)),
        ),
        if (info.isDesktop)
          ThreeColumnLayout()
        else if (info.isTablet)
          TwoColumnLayout()
        else
          SingleColumnLayout(),
      ],
    );
  },
);
디바이스별 완전히 다른 레이아웃
ResponsiveLayout(
  mobile: MobileHomePage(),   // Bottom nav, single column
  tablet: TabletHomePage(),   // Side drawer, 2 columns
  desktop: DesktopHomePage(), // Top nav, 3 columns, sidebar
);

BuildContext에서 직접 사용할 수 있는 헬퍼

카테고리헬퍼
디바이스 감지context.isMobile
context.isTablet
context.isDesktop
context.isLandscape
간격context.spacing(ResponsiveSpacing.md)
context.horizontalPadding()
context.safePadding
타이포그래피context.responsiveFontSize(18)
화면 헬퍼context.isNarrowScreen  //  1000 px (fold phones)

래퍼 없음. 보일러플레이트 없음.

의미론적 간격 값

간격모바일태블릿데스크톱
xs468
sm81216
md162432
lg243248
xl324864
xxl48

Source:

| 64 | 96 |

// Before
Container(
  padding: EdgeInsets.all(
    MediaQuery.of(context).size.width  ProductCard(),
    );
  }
}

advanced_responsive 사용

class ProductGrid extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ResponsiveBuilder(
      builder: (context, info) {
        final columns = info.responsiveValue(
          mobile: 2,
          tablet: 3,
          desktop: 4,
        );

        return GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: columns,
            mainAxisSpacing: info.spacing(ResponsiveSpacing.sm),
            crossAxisSpacing: info.spacing(ResponsiveSpacing.sm),
          ),
          itemBuilder: (context, index) => ProductCard(),
        );
      },
    );
  }
}

개선 사항

  • ✅ 더 깔끔하고 가독성 향상
  • ✅ 의미 있는 간격 값
  • ✅ 중앙에서 쉽게 수정 가능
  • ✅ 타입 안전한 디바이스 감지

서비스 예시 (캐싱)

class ResponsiveService {
  static final ResponsiveService _instance = ResponsiveService._internal();

  DeviceType? _cachedDeviceType;
  double? _cachedWidth;

  DeviceType getDeviceType(double width) {
    if (_cachedWidth == width) return _cachedDeviceType!;
    // … calculate and cache
  }
}

이점

  • 최소 오버헤드
  • 불필요한 재계산 없음
  • 효율적인 메모리 사용

실제 동작 보기

🌐 실시간 데모 시도

  1. 브라우저에서 링크를 엽니다.
  2. F12를 눌러 DevTools를 열고 반응형 헬퍼를 확인하세요.

📱 디바이스 툴바 전환

뷰포트 크기 조정

너비디바이스
320 px작은 모바일
600 px태블릿
840 px데스크톱
1200 px대형 데스크톱

관찰

  • 레이아웃 변경 (열, 네비게이션)
  • 간격 적용
  • 타이포그래피 스케일링
  • 그리드 열 변경

패키지 및 기능

기능advanced_responsiveresponsive_frameworkresponsive_builderflutter_screenutil
MD3 브레이크포인트❌ Custom❌ Custom❌ Custom
Adaptive 간격✅ Built‑in❌ Manual❌ Manual⚠️ Scaling only
Responsive 타이포그래피⚠️ Pixel‑based
Context 확장✅ Rich API⚠️ Limited⚠️ Basic⚠️ Limited
Zero config❌ Requires setup❌ Requires init
Grid 시스템✅ Auto
SafeArea 헬퍼
Dependencies0Multiple00
Package sizeSmallLargeSmallSmall

설치

dependencies:
  advanced_responsive: ^1.0.3
import 'package:advanced_responsive/advanced_responsive.dart';

최소 예시

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ResponsiveBuilder(
        builder: (context, info) => Scaffold(
          body: Padding(
            padding: context.safePadding,
            child: Text(
              'Hello Responsive World!',
              style: TextStyle(
                fontSize: context.responsiveFontSize(24),
              ),
    ```

> **Source:** ...

```dart
         ),
          ),
        ),
      ),
    );
  }
}

Do’s & Don’ts

padding: EdgeInsets.all(16)padding: EdgeInsets.all(context.spacing(ResponsiveSpacing.md))
Only when necessary
ResponsiveLayout( mobile: MobileView(), desktop: DesktopView(), )
Prefer adaptive
ResponsiveBuilder( builder: (context, info) => MyView( columns: info.responsiveValue(mobile: 1, tablet: 2, desktop: 3), ), )
Verbose
ResponsiveBuilder( builder: (context, info) { if (info.isMobile) { … } }, )
Concise
if (context.isMobile) { … }

Frequently Asked Questions

Q: Do I really need a responsive package?
A: No! That’s a common misconception. 90 % of apps only need the same UI with adaptive spacing, typography, and layout adjustments. The package handles this automatically.

Q: Can I migrate gradually?
A: Absolutely! You can migrate one screen at a time. The context extensions make it easy to replace existing MediaQuery calls incrementally.

Q: Is it cross‑platform?
A: Yes! The package is platform‑agnostic and works seamlessly across Mobile, Web, and Desktop.

Q: What’s the impact on app size?
A: Minimal – the package adds roughly ~50 KB to your app.

Q: Is it production‑ready?
A: Yes! It’s well‑tested, used in production apps, and actively maintained.

Feature Wishlist

  • Animated transitions between breakpoints
  • Debug overlay
  • Platform‑specific values
  • Responsive theme system
  • Custom breakpoint support
  • Performance improvements
  • CLI migration tool
  • Adaptive widgets library
  • Testing utilities

Why Choose advanced_responsive?

  • ✅ Reduces boilerplate
  • ✅ Enforces design consistency
  • ✅ Scales well as your project grows
  • ✅ Follows industry standards (Material Design 3)
  • ✅ Provides both adaptive and custom layout options

📦 pub.dev🐙 GitHub🌐 Live Demo

Found a bug? Have a feature request?

  • 🗳️ Vote on features: GitHub Discussions
  • 🤝 Contribute: Contributing Guide
  • 🐛 Open an issue
  • 🔧 Submit a PR: Fork the repo and contribute!
  • ⭐ Star on GitHub if you find it useful

About the Author

Sayed Moataz – Flutter developer passionate about building beautiful, responsive cross‑platform applications. This package was born from real‑world needs — solving responsive design challenges in multiple production projects.

  • 💼 LinkedIn:
  • 🐙 GitHub:
  • 📧 Email:
  • 📱 Flutter App Startup: From 30 seconds to under 1 second
  • 🔔 Building a Robust Notification Status Service in Flutter
  • 📊 Building a Robust Firebase Analytics Layer in Flutter

Happy coding! 🚀

If you found this article helpful, give it a ❤️ and follow for more Flutter content!

Back to Blog

관련 글

더 보기 »