2019年12月3日火曜日
1人 Flutter Advent Calendar 2019:#3 display resolution
前回のソースをQVGAのデバイス実行してみると以下のようになります。
色々とはみ出していてデザインが破綻しています。
ボタンが要素の右の端にあったらもう押すことも出来ないです。
Androidだけではなく、iOSでも画面の解像度にに種類があります。
FlutterではMediaQueryから取得できるsizeはLogical Pixelとされており、Deviceに関係なくだいたい同になるようにいい感じにやってくれます。Androidのdpみたいなもんですね。
しかし、画面自体が小さすぎれば当然、上の画像のように切れてしまいます。
Androidは画像やsizeの定義ファイルを解像度ごとにdirectoryで分けることで、こういった状況に対処します。
https://developer.android.com/training/multiscreen/screendensities?hl=ja
Flutterでも画像に関しては似たような回避策がありそうです。https://flutter.dev/docs/get-started/flutter-for/android-devs#where-do-i-store-my-resolution-dependent-image-files
しかし、widthやheightなどの値については回避策が無さそうでした。
また、デザインツールで出力されるものはwidhtなどが直値で指定されるので、これですべての解像度に対応するのは難しいです。
とはいえ、デザインツールで作成したものからは直値しかわかりません。
アプローチの方法は、Percentで指定する、全体にScaleをする、FlexBoxを利用してサイズに対して柔軟に対応するかだと思います。
Percent指定ですとflutter_screenutil というのがあります。
最初に画面のサイズを決めて、以降はutilityで提供されている関数でwidth/heightを指定します。
基本的には最初に設定したサイズでscaleしているだけになります。
ただ、これだと全体でScreenUtil.getInstance()を利用してサイズを指定しないとダメなので、ちょっと手間ですし、画面の縦横比に従って設定値を調整しないといけません。
https://github.com/matsuhiro/display_resolution_tests/blob/master/lib/main.dart#L189-L275
全体にScaleする方法につい
https://flutter.dev/docs/development/ui/widgets/layout
の中から利用できるものを選んで解決しました。
私の見た中ではFittedBoxが解決策に最適でした。
使った場所はこんなかんじです。
https://github.com/matsuhiro/display_resolution_tests/blob/master/lib/main.dart#L85-L87
全体のレイアウトは崩さずに全体的にScaleされます。
現実には、見栄えのために画面幅に応じたPaddingを入れるのが良いと思います。
これは、最大でも画面幅の90%になるようにPaddingを入れてあります。
これを解像度が大きい端末で実行すると
この様になって、全体にきれいに表示できると思いますし、解決策としても簡単に出来るのではないかと思います。
ここで扱ったサンプルは
https://github.com/matsuhiro/display_resolution_tests
にあります。
FlexBoxに関しては、また違う機会に扱おうと思います。
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿