iOSネイティブでは、1pixelを液晶の2ドット(レティナ:plus, x「以外」の端末)または3ドット(スーパーレティナ)で描画します。
Androidネイティブでは、1pixelを1ドットで描画しますが、各端末で同じような見た目と使い勝手を実現するため、サイズをdp(density-independent pixels:密度非依存ピクセル)で指定し、dpをpixelの代わりとして使い、dpを複数のドットで描画します。
つまり、1pixel (dp)を描画するのに、Android、iOS共に複数のドットが使われます。
プログラム上で描画するドットを、logical pixel(論理ピクセル)、実際に使われる液晶(有機EL)のドットをdevice pixel(物理ピクセル)と呼ぶようです。
描画に使うドットと端末のドットが混在しないように、この記事でもプログラム上のドットをlogical pixel、液晶のドットをdevice pixelと呼ぶことにします。
では、Flutterでサイズを数値指定した場合はどうなる?
Flutterでのlogical pixelとdevice pixelの関係はどうなっているのか?
Androidで実行した場合
Androidではなんと
1logical pixel = 1dp
となっています。
つまり、適当に44 x 44とサイズを指定すると、Androidの各端末でちゃんと同じような大きさで表示されます。
試しに、Nexus5 (1080 x 1920)の画面サイズを、MediaQuery.of(context).sizeで取得してみると
360 x 592
でした。
1logical pixel = 1dpにするため自動で画面サイズが変換されているので、画面サイズを取得した時、謎の数字が返ってきても混乱しないようにしてください。
iOSの場合
iOSは、iOSネイティブ開発者にとってとても自然な結果になっています。
レティナ端末の場合は
1logical pixel = 2device pixel
スーパーレティナ端末の場合は
1logical pixel = 3device pixel
になっていて、iOSネイティブを開発していた時と同じ感覚で数値を指定できます。
試しに、レティナ端末iPhone8 (750 x 1334)の画面サイズを、MediaQuery.of(context).sizeで取得してみると
375 x 667 (ちょうど半分)
スーパーレティナ端末iPhoneXS MAX (1242 x 2688)の画面サイズは
414 x 896 (ちょうど3分の1)
でした。
以上を踏まえて、Flutterでのサイズ指定をしてみてください。
twitterでは毎日技術情報をつぶやいていますので、フォロー宜しくお願い致します。