Flutter 端末サイズによってWidgetの大きさを比率で指定する方法

#はじめに
https://medium.com/flutter-community/flutter-effectively-scale-ui-according-to-different-screen-sizes-2cb7c115ea0a

上記を参考にしました。間違ってたらごめんなさい。。

#Widgetの大きさを固定すると
FlutterでUIを作る際に、**Widgetの大きさを固定値で指定するのはできるだけ避けたいところです。。。**


```dart
Container(
 height: 40,
 width: 60,
),
```

もし上記のように指定した場合、iPhone 5sとiPhone Xs Maxでは見た目のサイズ感が違っています。。

![スクリーンショット 2021-05-04 9.57.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/12f37074-502e-7cab-c916-dffdd18d2d73.jpeg)

なぜなら、Flutterはどの端末でアプリが実行されているかわからないため、`Container`は常に40 x 60となります。

#さまざまな画面サイズに応じてWidgetの大きさを比率で指定する
さてここから本題です。

どの画面サイズでも同じような大きさの比率でWidgetを表示させるために、画面をグリッドのように区切って「ブロック」ができるようにイメージします。

![スクリーンショット 2021-05-04 10.04.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/5b579557-5fb6-cae2-9a5f-6dc192082e49.jpeg)

**どの画面サイズでも「ブロック３つ分の横幅」みたいなサイズ指定をするイメージかと。**


##size_config.dartを作る

```dart:lib/config/size_config.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class SizeConfig {
  static MediaQueryData _mediaQueryData;
  static double screenWidth;
  static double screenHeight;
  static double blockSizeHorizontal;
  static double blockSizeVertical;

  static double _safeAreaHorizontal;
  static double _safeAreaVertical;
  static double safeBlockHorizontal;
  static double safeBlockVertical;

  void init(BuildContext context) {
    _mediaQueryData = MediaQuery.of(context);
    screenWidth = _mediaQueryData.size.width;
    screenHeight = _mediaQueryData.size.height;
    blockSizeHorizontal = screenWidth / 100;
    blockSizeVertical = screenHeight / 100;
  }
}
```


##SizeConfigを初期化して使う

```dart:lib/main.dart
import './config/size_config.dart';

class HomeScreen extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 SizeConfig().init(context);
 return Center(
  child: Container(
   height: SizeConfig.blockSizeVertical * 20,
   width: SizeConfig.blockSizeHorizontal * 50,
   color: Colors.orange,
  ),
 );
 }
```

これで長方形のサイズは、
**width : 画面の幅50%**
**height : 画面の高さ20%**

となります！！！

![スクリーンショット 2021-05-04 12.11.44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/4dd35752-e04d-5e67-94d5-d3a965bb6fd3.jpeg)



この`SizeConfig`はあらゆる場面で汎用的に使えると思うので、Flutter開発者は知っておいて損はないでしょう:relieved:

説明が間違ってりしたら教えてください！

#追記(null safetyに対応したバージョン！)
無理やりではありますが、`size_config.dart`をnull safetyに対応させてみました！

```dart:lib/config/size_config.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class SizeConfig {
  static MediaQueryData? _mediaQueryData;
  static double? screenWidth;
  static double? screenHeight;
  static double? blockSizeHorizontal;
  static double? blockSizeVertical;

  static double? _safeAreaHorizontal;
  static double? _safeAreaVertical;
  static double? safeBlockHorizontal;
  static double? safeBlockVertical;

  void init(BuildContext context) {
    _mediaQueryData = MediaQuery.of(context);
    screenWidth = _mediaQueryData!.size.width;
    screenHeight = _mediaQueryData!.size.height;
    blockSizeHorizontal = screenWidth! / 100;
    blockSizeVertical = screenHeight! / 100;

    _safeAreaHorizontal =
        _mediaQueryData!.padding.left + _mediaQueryData!.padding.right;
    _safeAreaVertical =
        _mediaQueryData!.padding.top + _mediaQueryData!.padding.bottom;
    safeBlockHorizontal = (screenWidth! - _safeAreaHorizontal!) / 100;
    safeBlockVertical = (screenHeight! - _safeAreaVertical!) / 100;
  }
}
```

👆でいいのかな？？？
あんまりわかっていないので、どなたか助言あればお願いします！！:bow: