중급
Adaptive와 Responsive 디자인
화면 크기와 입력 방식이 다른 환경에서도 자연스러운 UI를 만듭니다.
핵심 개념
Adaptive와 Responsive 디자인 주요 항목
Responsive
화면 크기에 따라 레이아웃, 열 수, 여백, 내비게이션 방식을 조정합니다.
언제 쓰나: 모바일에서는 단일 컬럼, 태블릿과 데스크톱에서는 다중 컬럼이 자연스러울 수 있습니다.
Flutter에서: LayoutBuilder와 MediaQuery를 적절히 사용해 컴포넌트 단위로 반응형을 설계합니다.
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Responsive', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text('화면 크기에 따라 레이아웃, 열 수, 여백, 내비게이션 방식을 조정합니다.'),
],
),
),
)
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFEEF7FB),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'Responsive',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900),
),
)
],
),
)
Responsive
Adaptive
플랫폼 관습에 맞춰 UI나 동작을 조정하는 접근입니다.
언제 쓰나: 마우스, 키보드, 터치, 접근성 설정 등 입력 방식도 함께 고려합니다.
Flutter에서: 자동 플랫폼 적응 위젯에만 의존하지 말고 사용자 흐름을 직접 점검합니다.
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Adaptive', style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Text('플랫폼 관습에 맞춰 UI나 동작을 조정하는 접근입니다.'),
],
),
),
)
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFEEF7FB),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'Adaptive',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w900),
),
)
],
),
)
Adaptive
확장 개념
SafeArea와 MediaQuery
- SafeArea는 노치, 상태바, 홈 인디케이터처럼 시스템 UI와 겹치지 않도록 여백을 확보합니다.
- MediaQuery는 화면 크기, 방향, 접근성 텍스트 크기 같은 환경 정보를 제공합니다.
- LayoutBuilder는 부모가 준 실제 제약을 기준으로 UI를 나눌 때 사용합니다.
확장 개념
큰 화면과 입력 방식
- 태블릿과 데스크톱에서는 한 화면에 더 많은 정보를 보여주되, 밀도만 높이지 말고 탐색 구조도 함께 조정합니다.
- 마우스, 키보드, 터치 입력이 모두 가능한 환경에서는 hover, focus, shortcut 상태를 고려합니다.
- 반응형 UI는 단순히 폭만 보는 것이 아니라 사용자가 어떤 방식으로 조작하는지도 함께 봅니다.
코드
예제
LayoutBuilder(
builder: (context, constraints) {
final wide = constraints.maxWidth >= 700;
return wide ? const WideLayout() : const CompactLayout();
},
)
LayoutBuilder(
builder: (context, constraints) {
final wide = constraints.maxWidth >= 420;
return Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
border: Border.all(color: const Color(0xFFDCE6EF)),
borderRadius: BorderRadius.circular(8),
),
child: GridView.count(
shrinkWrap: true,
crossAxisCount: wide ? 3 : 1,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: const [
_PreviewTile('목록'),
_PreviewTile('상세'),
_PreviewTile('도구'),
],
),
);
},
)
Flutter Wiki
다음 단계
실습 체크리스트
breakpoint 정의LayoutBuilder 사용입력 방식과 접근성 고려
- 출처세부 기준과 최신 변경 사항을 확인할 수 있습니다.
- Flutter API Reference클래스, 메서드, 생성자 세부 정의를 확인합니다.
- Flutter UI위젯, 레이아웃, 입력, 내비게이션 흐름을 함께 봅니다.