flutterではwidgetのサイズを指定する際、論理ピクセルを用いる。
論理ピクセルを用いるとデバイスごとに異なる物理解像度を意識せずにUIを作成できる
本エントリでは論理ピクセルについての基礎知識と使用する際の注意点についてを以下の流れで説明する。
論理ピクセルとは
実際のデバイスごとに規定されているサイズの最小単位のこと。
例えば論理ピクセル上で幅が390のwidgetがあったとする。これをiPhone 12 Proで表示したとすると、widgetの幅はディスプレイいっぱいになる。iPhone 12 Proのディスプレイの幅が390論理ピクセルと規定されているためContainerは画面いっぱいに広がる。
シミュレーター上での表示とコードは次のようになる。
Container( height: 100, width: 390, decoration: BoxDecoration(color: Colors.blueAccent), ),
次にシミュレーターを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シミュレーター上での表示とコードは以下。
Container( height: 100, width: MediaQuery.of(context).size.width, decoration: BoxDecoration(color: Colors.blueAccent), )
ただし使用する際widgetにラップされていると、MediaQuery.of(context).size
のサイズは親widgetに依存する。
例えば以下の場合、Containerの幅は画面いっぱいに広がらない。
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シミュレーター上での表示とコードは以下。
child: Container( height: 100, width: double.infinity, decoration: BoxDecoration(color: Colors.blueAccent), ),