📱

Flutterでレスポンシブ対応をしてみる

2023/09/16に公開

Overview

https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html
公式を翻訳
親ウィジェットのサイズに依存できるウィジェットツリーを構築します。

フレームワークがレイアウト時にビルダー関数を呼び出し、親ウィジェットの制約を提供する点を除き、ビルダーウィジェットに似ています。これは、親が子のサイズを制約し、子の固有サイズに依存しない場合に便利です。LayoutBuilder の最終サイズは、子のサイズと一致します。

ビルダー関数は次のような状況で呼び出されます:

ウィジェットが初めてレイアウトされるとき。
親ウィジェットが異なるレイアウト制約を渡すとき。
親ウィジェットがこのウィジェットを更新したとき。
ビルダ関数がサブスクライブする依存関係が変更されたとき。
親ウィジェットが同じ制約を繰り返し渡す場合、ビルダ関数はレイアウト中に呼び出されません。

summary

Flutterで画面サイズに対応したレイアウトをしたい場合があります。
Web開発でいうところのレスポンシブ対応ですね。LayoutBuilderを使うと画面サイズによって表示方法を変更することができます。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Responsive Layout',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: ResponsiveLayout(),
    );
  }
}

class ResponsiveLayout extends StatelessWidget {
  const ResponsiveLayout({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Responsive Layout using LayoutBuilder'),
      ),
      // LayoutBuilderを使って画面サイズに応じてレイアウトを変更
      body: LayoutBuilder(
        builder: (context, constraints) {
          // 画面幅に応じて表示する列数を変更
          int crossAxisCount;
          double width = constraints.maxWidth;// 画面幅を取得
          // PCサイズ以上の場合は4列
          if (width >= 800) {
            crossAxisCount = 4;
          // タブレットサイズの場合は3列
          } else if (width >= 500) {
            crossAxisCount = 3;
          // スマホサイズの場合は1列
          } else {
            crossAxisCount = 1;
          }
          // GridViewを返す
          return GridView.builder(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: crossAxisCount,// 列数
              childAspectRatio: 1,// アスペクト比
            ),
            itemBuilder: (context, index) => Container(
              margin: const EdgeInsets.all(10),
              width: 200,
              height: 200,
              color: Colors.grey,
            ),
            itemCount: 12, // グレーのコンテナを12個表示
          );
        },
      ),
    );
  }
}

Flutter Webでのブラウザ対応したサイズ
ブラウザで表示する広い画面だとこんな感じですね。

iPadに対応したサイズ
iPadに対応したサイズだとこんな感じですね。

iPhoneに対応したサイズ
iPhone14に対応したサイズでしたらこんな感じになります。

thoughts

今回は色をつけた只の箱ですが、端末のサイズごとに表示する方法を変更してみました。もっとパーツが多いUIじゃないと参考にならないかもと思いましたが、複雑だと作るの大変なので今回は簡単なものでやってみました。
ご興味ある方は、タブメニューなどをいっぱい並べて実験してみてください。

Jboy王国メディア

Discussion