Flutter Expanded와 MediaQuary

Ruinak·2021년 10월 16일
0

Flutter

목록 보기
7/12
post-thumbnail

Column

  • 가로는 가지고 있지만 세로는 가지고 있지 않으므로 height를 이용해서 높이를 지정해줘야합니다.
 body: Column(
  // Column은 배열로 감싸져 있음
  children: [
    Container(
      height: 500,
      color: Colors.blue,
    ),
  ],
),

Expanded

  • Expanded를 사용하면 남은 여백을 모두 차지하게 됩니다.
 body: Column(
   // Column은 배열로 감싸져 있음
   children: [
     Container(
       height: 500,
       color: Colors.blue,
     ),
     Expanded(
       child: Container(
         color: Colors.red,
       ),
     ),
   ],
 ),
  • Expanded를 사용하면 설정된 height 값을 무시합니다.
 body: Column(
   // Column은 배열로 감싸져 있음
   children: [
     Expanded(
       child: Container(
         height: 500,
         color: Colors.blue,
       ),
     ),
     Expanded(
       child: Container(
         color: Colors.red,
       ),
     ),
   ],
 ),

flex

  • Expanded 내부에 flex를 사용하면 비율을 지정해줄 수 있습니다.
  • 높이를 굉장히 유연하게 맞출 수 있습니다.
body: Column(
  // Column은 배열로 감싸져 있음
  children: [
    Expanded(
      flex: 9,
      child: Container(
        color: Colors.blue,
      ),
    ),
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.red,
      ),
    ),
  ],
),
  • 높이를 억지로 지정을 해야한다면 height: 500과 같은 방식으로 주면 디바이스마다 비율이 다르므로 매우 좋지 않습니다.
  • 이때 사용하는 것이 MediaQuery입니다.

MediaQuery

  • MediaQuery는 디바이스의 크기를 알려줍니다.
  • var m = MediaQuery.of(context);를 이용해서 확인할 수 있습니다.
...

@override
Widget build(BuildContext context) {
  var m = MediaQuery.of(context);
  print("넓이 : ${m.size.width}");
  print("높이 : ${m.size.height}");
    return MaterialApp(
    ...
  • MediaQuery의 특이한 점은 최초의 처음 실행되는 위젯(여기서는 FirstApp)에서는 실행이 안됩니다.
  • HomeApp()이라는 위젯을 새로 만들고 그 안에서 MediaQuery를 사용합니다.
  • Scaffold가 부모라서 크기를 잴 수 없는 것 같습니다.
class FirstApp extends StatelessWidget {
  const FirstApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Scaffold(
          // Column은 가로는 가지고 있지만 세로는 가지고 있지 않음
          body: HomeApp(),
        ),
      ),
    );
  }
}

class HomeApp extends StatelessWidget {
  const HomeApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var m = MediaQuery.of(context);
    print("넓이 : ${m.size.width}");
    print("높이 : ${m.size.height}");
    return Column(
      // Column은 배열로 감싸져 있음
      children: [
        Expanded(
          flex: 9,
          child: Container(
            color: Colors.blue,
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.red,
          ),
        ),
      ],
    );
  }
}
  • 콘솔을 확인해보면 디바이스의 넓이와 높이를 확인할 수 있습니다.
  • SafeArea의 영역때문에 디바이스의 높이가 줄어드므로, SafeArea의 높이만큼은 값을 빼줘야 합니다.
  • SafeArea의 padding 값을 확인하기 위해서는 SafeArea를 적용시키지 않은 상태에서 확인해야합니다.
class HomeApp extends StatelessWidget {
  const HomeApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var m = MediaQuery.of(context);
    print("넓이 : ${m.size.width}");
    print("높이 : ${m.size.height}");
    // SafeArea를 확인하기 위해서는 FirstApp의 SafeArea를 지우고 확인해야 함
    print("SafeArea : ${m.padding.top}");
    return Column(
      // Column은 배열로 감싸져 있음
      children: [
        Container(
          height: (m.size.height - 24) * 0.7,
          color: Colors.blue,
        ),
        Container(
          height: (m.size.height - 24) * 0.3,
          color: Colors.red,
        ),
      ],
    );
  }
}
  • 위 화면은 7:3의 비율이며, 소수점 값을 조정하면 비율을 조정할 수 있습니다.
  • 24의 값은 현재 디바이스에서의 SafeArea가 차지하는 높이이며, 디바이스마다 값이 다르므로 확인은 필수입니다.

전체 코드

// ignore_for_file: 
// prefer_const_literals_to_create_immutables, prefer_const_constructors
import 'package:flutter/material.dart';

// main 스레드는 runApp 을 실행시키고 종료됩니다.
void main() {
  // 비동기로 실행됨(이벤트 루프에 등록된다)
  runApp(FirstApp());
  // sleep(Duration(seconds: 2));
  // print("main 종료");
}

class FirstApp extends StatelessWidget {
  const FirstApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: Scaffold(
          // Column은 가로는 가지고 있지만 세로는 가지고 있지 않음
          body: HomeApp(),
        ),
      ),
    );
  }
}

class HomeApp extends StatelessWidget {
  const HomeApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var m = MediaQuery.of(context);
    print("넓이 : ${m.size.width}");
    print("높이 : ${m.size.height}");
    // SafeArea를 확인하기 위해서는 FirstApp의 SafeArea를 지우고 확인해야 함
    print("SafeArea : ${m.padding.top}");
    return Column(
      // Column은 배열로 감싸져 있음
      children: [
        Container(
          height: (m.size.height - 24) * 0.5,
          color: Colors.blue,
        ),
        Container(
          height: (m.size.height - 24) * 0.5,
          color: Colors.red,
        ),
      ],
    );
  }
}
profile
Nil Desperandum <절대 절망하지 마라>

0개의 댓글