1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flutter のレスポンシブ(適応型) UI

Posted at

Flutter のレスポンシブ(適応型) UI を実現するための代表的な手法をいくつか紹介します。

  • フレックスレイアウト(Flex/Expanded/Flexible)
  • MediaQuery で画面サイズを取得
  • LayoutBuilder で親コンテナの制約に応じる
  • FractionallySizedBox/AspectRatio で割合指定
  • OrientationBuilder で縦横向き切り替え
  • FittedBox や Expanded+FittedBox
  • サードパーティパッケージの活用(responsive_framework,flutter_layout_grid,flutter_screenutil,auto_size_text )

フレックスレイアウト(Flex/Expanded/Flexible)

主に水平方向(Row)か垂直方向(Column)に子ウィジェットを「比率」で分配したり、「空きスペース」を自動で埋めたりするのに使います。

Row(
  children: [
    Expanded(flex: 2, child: Container(color: Colors.blue, height: 100)),
    Expanded(flex: 1, child: Container(color: Colors.red,  height: 100)),
  ],
)

MediaQuery で画面サイズを取得

  • 画面幅・高さに応じてウィジェットツリーを切り替え可能
final size = MediaQuery.of(context).size;
if (size.width > 600) {
  // タブレット以上向けのレイアウト
} else {
  // スマホ向けレイアウト
}

LayoutBuilder で親コンテナの制約に応じる

画面だけでなく、カードコンテナやダイアログなど局所的にも適用できる。

LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth > 800) {
      return _buildWideLayout();
    } else {
      return _buildNarrowLayout();
    }
  },
)

割合指定

FractionallySizedBox:親の何%幅/高さにするか指定
FractionallySizedBox(
  widthFactor: 0.7,
  child: Container(color: Colors.red),
);

AspectRatio:子のアスペクト比を固定
AspectRatio(
  aspectRatio: 16 / 9,
  child: Container(color: Colors.black),
);

OrientationBuilder で縦横向き対応

  • 端末の回転(Portrait/Landscape)に合わせてレイアウト変更
OrientationBuilder(
  builder: (context, orientation) {
    return orientation == Orientation.portrait
      ? _buildPortrait()
      : _buildLandscape();
  },
)

FittedBox

  • 子のサイズが親を超えないよう、自動でスケールダウン
FittedBox(
  fit: BoxFit.scaleDown,
  child: Text('とても長いテキストを自動で縮小'),
);

responsive_framework

  • [MOBILE/TABLET/DESKTOP」のように幅ごとに自動調整

  • レスポンシブグリッドや行列レイアウトも提供


    ResponsiveBreakpoints.builder(
        child: child!,
        breakpoints: [
          const Breakpoint(start: 0, end: 450, name: MOBILE),
          const Breakpoint(start: 451, end: 800, name: TABLET),
          const Breakpoint(start: 801, end: 1920, name: DESKTOP),
          const Breakpoint(start: 1921, end: double.infinity, name: '4K'),
        ],
      )

flutter_layout_grid

flutter_layout_grid は CSS Grid のような二次元グリッドレイアウトを Flutter で実現するライブラリです。複雑な行・列の配置や自動フローを簡潔に書けるのが特徴です。

    LayoutGrid(
        areas: '''
          header header  header
          nav    content aside
          nav    content .
          footer footer  footer
        ''',
        // Concise track sizing extension methods 
        columnSizes: [152.px, 1.fr, 152.px],
        rowSizes: [
          112.px,
          auto,
          1.fr,
          64.px,
        ],
        // Column and row gaps! 
        columnGap: 12,
        rowGap: 12,
        // Handy grid placement extension methods on Widget 
        children: [
          Header().inGridArea('header'),
          Navigation().inGridArea('nav'),
          Content().inGridArea('content'),
          Aside().inGridArea('aside'),
          Footer().inGridArea('footer'),
        ],
      ),

flutter_screenutil

flutter_screenutil は、デザインカンプ(例:375×812pt)に基づいて、UI のあらゆる長さ・幅・フォントサイズ・角丸などを「実機画面サイズに等比マッピング」してくれるパッケージです。具体的には、以下のような拡張プロパティを提供します。

.w / .h:幅(width)、高さ(height)を designSize に対してスケール

.sp:フォントサイズを designSize に対してスケール

.r:半径(radius)、境界線の太さなどをスケール

.sw / .sh:画面幅・画面高さのパーセント指定

void main() {
  runApp(
    ScreenUtilInit(
      designSize: Size(375, 812), // ここはデザインカンプのサイズ
      minTextAdapt: true,          // 文字も最小限適応させるか
      builder: (context, child) {
        return MaterialApp(
          home: child,
        );
      },
      child: MyApp(),
    ),
  );
}

Container(
      width: 300.w,           // designSize の (300/375) × 実機幅
      height: 200.h,          // designSize の (200/812) × 実機高
      alignment: Alignment.center,
      child: Text(
        'ScreenUtil Sample',
        style: TextStyle(fontSize: 16.sp), // (16/375) × 実機幅
      ),
    )

auto_size_text

AutoSizeText は、長いテキストを親コンテナに収めつつ、文字サイズを自動で縮小してくれる Flutter のパッケージです。

AutoSizeText(
  'Flutter は素晴らしい UI フレームワークです!長いテキストも自動で縮小。',
  style: TextStyle(fontSize: 24),
  maxLines: 2,               // 2行まで表示
  minFontSize: 12,           // 縮小しても 12 が下限
  stepGranularity: 2,        // 24→22→20→…と 2 ずつ縮小
  overflowReplacement: Text('…'), // 縮小限界を超えたら代替ウィジェット
)

まとめ

1.まずは Flutter 標準で

  • Flex 系、MediaQuery、LayoutBuilder、FractionallySizedBox、FittedBox

2.必要に応じてサードパーティ

  • デザイン通り等比なら flutter_screenutil
  • ブレイクポイント重視なら responsive_framework

サードパーティパッケージ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?