[Flutter/Widgets] 반응형(Responsive) 위젯 Flexible과 Expanded

2021. 7. 11. 19:21·Flutter/Widgets
반응형

Flexible과 Expanded은 Flutter에서 반응형 어플리케이션을 만들기 위해 사용하는 Widget 입니다.

두 위젯의 목적은 반응형 디자인입니다. 즉, Flutter 앱이 화면 크기에 따라 변경되고 적응하는 것입니다. 두 위젯 모두 Column과 Row와 밀접한 연관이 있으며, 상위 Column과 Row의 기본축에 연관된 하위 위젯들을 Responsive하게 사이즈를 변경 시켜줍니다.

Flexible

속성

Flexible(
         flex: 1, // default
         fit: FlexFit.loose, // default
         child: Container(),// required field
       ),

fit: Column 혹은 Row 기본축의 남은 공간을 어떻게 차지 하게 할 것인지를 정해주는 속성

1. FlexFit.tight : 기본축의 남은 공간을 전부 채우도록 합니다.

2. FlexFit.loose : 기본축의 남은 공간을 채우도록 하되 필요한 공간만 차지하도록 합니다.

flex: Column 혹은 Row 기본축의 남은공간을 flex 값 / 전체 자식들의 flex의 합만큼 차지하도록 합니다.

예제

1. Flexible을 사용하지 않은 위젯이 화면의 크기를 넘어갈 경우

Row(
  children: [
    Container(
      width: 300,
      height: 100,
      color: Colors.blue,
    ),
    Container(
      width: 600,
      height: 100,
      color: Colors.green,
    ),
  ],
),

위젯이 화면의 크기를 넘어갈 경우, 당연하게도 에러가 발생하게 됩니다.

2. Flexible fit 속성 FlexFit.loose(Default) 사용

Row가 화면의 크기를 넘어갈 경우

Row(
  children: [
    Container( 
      width: 300,
      height: 100,
      color: Colors.blue,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        width: 600,
        height: 100,
        color: Colors.green,
      ),
    ),
  ],
)

FlexFit.loose - 화면의 크기를 넘어갈 때

만약, 화면의 크기를 넘어가는 Row에서 자식 위젯을 Flexible로 위젯을 감쌀 경우, 화면의 남는 필요한 공간만 차지하게 되어 에러발생을 하지 않게됩니다.

Row가 화면의 크기를 안넘을 경우

Row(
  children: [
    Container(
      width: 300,
      height: 100,
      color: Colors.blue,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        width: 50,
        height: 100,
        color: Colors.green,
        ),
      ),
    ],
),

FlexFit.loose - 화면의 크기를 안넘을 때

두번째 위젯의 크기가 화면의 크기를 넘어가지 않는다면 필요한 공간만 차지합니다. (wrap_content와 동일하게 작동)

만약, Column이나 Row가 화면의 크기에 따라 넘치거나 할 가능성이 조금이라도 존재한다면 Flexible을 사용하여 반응형으로 만드는 것이 안전합니다.

3. Flexible fit 속성 FlexFit.tight 사용

Row(
  children: [
    Container(
      width: 100,
      height: 100,
      color: Colors.blue,
    ),
    Flexible(
      fit: FlexFit.tight,
      child: Container(
        width: 50,
        height: 100,
        color: Colors.green,
      ),
    ),
  ],
),

FlexFit.tight를 속성으로 줄 경우, 남은 공간을 전부 차지하게 됩니다.

4. Flexible flex 속성 사용

Row(
  children: [
    Flexible(
    flex: 3,
    child: Container(
      height: 100,
      color: Colors.blue,
      ),
    ),
    Flexible(
      flex: 2,
      child: Container(
        height: 100,
        color: Colors.green,
        ),
      ),
    Flexible(
      flex: 1,
      child: Container(
        height: 100,
        color: Colors.red,
      ),
    ),
  ],
),

남은공간을 파랑, 초록, 빨강이 1/2, 1/3, 1/6 (flex 값 / 전체 자식들의 flex의 합) 비율 만큼 차지하게 됩니다.

Expanded

Expanded는 Flexible with FlexFit.tight의 줄임말 입니다.

Row(
  children: [
    Container(
      width: 300,
      height: 100,
      color: Colors.blue,
    ),
    Expanded(
      child: Container(
      height: 100,
      color: Colors.green,
      ),
    ),
  ],
),

Expanded

Flexible(FlexFit.tight)와 동일하게 파란부분이 차지하는 부분 외에 남은 공간을 초록 색상이 차지합니다.

전체코드

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FlexibleExpandedScreen(title: 'Flexible Expanded Example'),
    );
  }
}


class FlexibleExpandedScreen extends StatefulWidget {
  final String title;

  FlexibleExpandedScreen({required this.title});

  @override
  _FlexibleExpandedScreenState createState() => _FlexibleExpandedScreenState();
}

class _FlexibleExpandedScreenState extends State<FlexibleExpandedScreen> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Text(
                  'overflowed widgets',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Container(
                      width: 300,
                      height: 100,
                      color: Colors.blue,
                    ),
                    Container(
                      width: 600,
                      height: 100,
                      color: Colors.green,
                    ),
                  ],
                ),
                SizedBox(
                  height: 16.0,
                ),
                Text(
                  'Flexible FlexFit loose',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Container(
                      width: 300,
                      height: 100,
                      color: Colors.blue,
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                        width: 600,
                        height: 100,
                        color: Colors.green,
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 16.0,
                ),
                Text(
                  'Flexible FlexFit loose',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Container(
                      width: 300,
                      height: 100,
                      color: Colors.blue,
                    ),
                    Flexible(
                      fit: FlexFit.loose,
                      child: Container(
                        width: 50,
                        height: 100,
                        color: Colors.green,
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 16.0,
                ),
                Text(
                  'Flexible FlexFit tight',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Container(
                      width: 100,
                      height: 100,
                      color: Colors.blue,
                    ),
                    Flexible(
                      fit: FlexFit.tight,
                      child: Container(
                        width: 50,
                        height: 100,
                        color: Colors.green,
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 16.0,
                ),
                Text(
                  'Flexible flex',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Flexible(
                      flex: 3,
                      child: Container(
                        height: 100,
                        color: Colors.blue,
                      ),
                    ),
                    Flexible(
                      flex: 2,
                      child: Container(
                        height: 100,
                        color: Colors.green,
                      ),
                    ),
                    Flexible(
                      flex: 1,
                      child: Container(
                        height: 100,
                        color: Colors.red,
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height: 16.0,
                ),
                Text(
                  'Expanded',
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Row(
                  children: [
                    Container(
                      width: 300,
                      height: 100,
                      color: Colors.blue,
                    ),
                    Expanded(
                      child: Container(
                        height: 100,
                        color: Colors.green,
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
반응형
'Flutter/Widgets' 카테고리의 다른 글
  • [Flutter] SingleChildScrollView의 중앙에 위젯 배치하기
  • [Flutter/Widgets] 키보드 위에 떠있는 버튼 만들기(ButtonAboveKeyboard) 만들기(feat. MediaQuery.of(context).viewInsets)
  • [Flutter/Widgets] Flutter 2.0 새로운 Material Buttons (FlatButton, RaisedButton, OutlineButton Deprecated)
seunghwaan
seunghwaan
공부한 내용을 정리하는 개발 기록 블로그
    반응형
  • seunghwaan
    SH's Devlog
    seunghwaan
  • 전체
    오늘
    어제
    • 분류 전체보기 (150)
      • Android (62)
        • Basic (17)
        • Kotlin(Java) (14)
        • UI & Animation (1)
        • Compose (2)
        • Coroutines (1)
        • Dependency Injection (6)
        • RxJava (8)
        • BLE (3)
        • TDD (2)
        • JetPack (1)
        • NextStep (4)
        • Error Log (3)
      • Flutter (14)
        • Basic (5)
        • Dart (1)
        • State Management (2)
        • Widgets (4)
        • Error and Tips (2)
      • iOS (8)
        • Basic (0)
        • Swift (8)
      • Web Frontend (6)
        • Basic (0)
        • JavaScript (5)
        • TypeScript (0)
        • React (1)
      • CS(Computer Science) (18)
        • Network (4)
        • Database (10)
        • Design Pattern (1)
        • Computer Architecture (3)
        • Operating System (0)
      • Cloud (6)
        • AWS (6)
      • DevOps (25)
        • GIT (4)
        • CI CD (8)
        • Linux (4)
        • Docker (9)
        • Error Log (0)
      • 코딩테스트 (10)
        • DB (6)
        • 알고리즘 (4)
      • Backend (1)
        • Spring (1)
      • Mac Tip (0)
      • Language (0)
        • English (0)
        • Japanese (0)
      • Temporary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Android
    gradle
    Swift
    Dagger
    cognito
    Network
    Computer Science
    MySQL
    CI
    Kotlin
    AWS
    error
    시작하세요! 도커
    RxJava
    CICD
    상태 관리
    컴퓨터공학
    Jenkins
    IOS
    FLUTTER
    BLE
    JavaScript
    database
    Algorithm
    di
    Linux
    docker
    네트워크
    Dependency Injection
    cs
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
seunghwaan
[Flutter/Widgets] 반응형(Responsive) 위젯 Flexible과 Expanded
상단으로

티스토리툴바