すらぼうの開発ノート

モバイルアプリエンジニアのメモ

【Flutter】論理ピクセルでwidgetのサイズを指定する

flutterではwidgetのサイズを指定する際、論理ピクセルを用いる。

論理ピクセルを用いるとバイスごとに異なる物理解像度を意識せずにUIを作成できる

本エントリでは論理ピクセルについての基礎知識と使用する際の注意点についてを以下の流れで説明する。

論理ピクセルとは

実際のデバイスごとに規定されているサイズの最小単位のこと。

例えば論理ピクセル上で幅が390のwidgetがあったとする。これをiPhone 12 Proで表示したとすると、widgetの幅はディスプレイいっぱいになる。iPhone 12 Proのディスプレイの幅が390論理ピクセルと規定されているためContainerは画面いっぱいに広がる。

シミュレーター上での表示とコードは次のようになる。

iphone 12 pro

Container(
  height: 100,
  width: 390,
  decoration: BoxDecoration(color: Colors.blueAccent),
),

次にシミュレーターをiPhone 12 Pro Maxに変更して同じコードを実行すると次のように表示される。

iphone 12 pro max

containerが画面いっぱいに広がっておらず、両サイドに隙間ができている。これはiPhone 12 Pro Maxのディスプレイ幅が論理ピクセル上では428であるため。

flutterで論理ピクセルを扱う際の注意と対策

基本的にデバイスごとにアプリの表示は揃えた方が良い。そのためレイアウト系のwidgetの場合上記の例のようにwidgetサイズを直接数値で入力することは避けることが多い。

対策はいくつかあるが、例えば次の方法を現場ではよく目にする。

MediaQuery.of(context).size.width

MediaQuery.of(context).sizeはデバイスごとの論理ピクセルを取得できる。iPhone 12 Pro Maxシミュレーター上での表示とコードは以下。

api.flutter.dev

mediaquery

Container(
  height: 100,
  width: MediaQuery.of(context).size.width,
  decoration: BoxDecoration(color: Colors.blueAccent),
)

ただし使用する際widgetにラップされていると、MediaQuery.of(context).sizeのサイズは親widgetに依存する。 例えば以下の場合、Containerの幅は画面いっぱいに広がらない。

iphone 12 pro max

SizedBox(
  width: 200,
  child: Container(
    height: 100,
    width: MediaQuery.of(context).size.width,
    decoration: BoxDecoration(color: Colors.blueAccent),
  ),
)

なので画面いっぱいwidgetのサイズを広げる場合は、widget tree上でサイズを規定している親widgetがいないかを確認する。

double.infinity

double.infinityは無限大値をdouble型で返す。そのためwidgetサイズは最大値に設定される。ただしこの方法も親widgetに依存したサイズになる。

iPhone 12 Pro Maxシミュレーター上での表示とコードは以下。

api.flutter.dev

iphone 12 pro max

child: Container(
  height: 100,
  width: double.infinity,
  decoration: BoxDecoration(color: Colors.blueAccent),
),

参照リソース

ios device

www.ios-resolution.com

andoid device

yesviz.com