📱
Flutterでレスポンシブ対応をしてみる
Overview
親ウィジェットのサイズに依存できるウィジェットツリーを構築します。
フレームワークがレイアウト時にビルダー関数を呼び出し、親ウィジェットの制約を提供する点を除き、ビルダーウィジェットに似ています。これは、親が子のサイズを制約し、子の固有サイズに依存しない場合に便利です。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じゃないと参考にならないかもと思いましたが、複雑だと作るの大変なので今回は簡単なものでやってみました。
ご興味ある方は、タブメニューなどをいっぱい並べて実験してみてください。
Discussion