Flutter Build Responsive Layout

作者 flutter0ef3972f93e2無授權條款3K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫2 天前更新

Use `LayoutBuilder`, `MediaQuery`, or `Expanded/Flexible` to create a layout that adapts to different screen sizes. Use when you need the UI to look good on both mobile and tablet/desktop form factors.

AI 產生的概覽

指導 Flutter 開發者建立能適應不同螢幕與視窗尺寸的響應式版面。

功能
此技能提供使用 LayoutBuilder、MediaQuery 與 Expanded/Flexible 實作自適應 Flutter 版面的說明與 Dart 程式碼範例。內容涵蓋可用空間測量、條件約束套用、裝置與方向行為處理,以及大螢幕最佳化。它產出的是指引與範例元件樹,而非可執行的指令碼。
適用情境
當 Flutter 介面需要在手機、平板、桌面等不同外型或可調整視窗中正常顯示時使用。它適合用來避免溢出、橫向拉伸與方向相關的版面問題。
執行需求
此技能未附帶指令碼或套件,假定具備 Flutter/Dart 開發環境並熟悉 Flutter 元件。

Implementing Adaptive Layouts

Contents

Space Measurement Guidelines

Determine the available space accurately to ensure layouts adapt to the app window, not just the physical device.

  • Use MediaQuery.sizeOf(context) to get the size of the entire app window.
  • Use LayoutBuilder to make layout decisions based on the parent widget's allocated space. Evaluate constraints.maxWidth to determine the appropriate widget tree to return.
  • Do not use MediaQuery.orientationOf or OrientationBuilder near the top of the widget tree to switch layouts. Device orientation does not accurately reflect the available app window space.
  • Do not check for hardware types (e.g., "phone" vs. "tablet"). Flutter apps run in resizable windows, multi-window modes, and picture-in-picture. Base all layout decisions strictly on available window space.

Widget Sizing and Constraints

Understand and apply Flutter's core layout rule: Constraints go down. Sizes go up. Parent sets position.

  • Distribute Space: Use Expanded and Flexible within Row, Column, or Flex widgets.
    • Use Expanded to force a child to fill all remaining available space (equivalent to Flexible with fit: FlexFit.tight and a flex factor of 1.0).
    • Use Flexible to allow a child to size itself up to a specific limit while still expanding/contracting. Use the flex factor to define the ratio of space consumption among siblings.
  • Constrain Width: Prevent widgets from consuming all horizontal space on large screens. Wrap widgets like GridView or ListView in a ConstrainedBox or Container and define a maxWidth in the BoxConstraints.
  • Lazy Rendering: Always use ListView.builder or GridView.builder when rendering lists with an unknown or large number of items.

Device and Orientation Behaviors

Ensure the app behaves correctly across all device form factors and input methods.

  • Do not lock screen orientation. Locking orientation causes severe layout issues on foldable devices, often resulting in letterboxing (the app centered with black borders). Android large format tiers require both portrait and landscape support.
  • Fallback for Locked Orientation: If business requirements strictly mandate a locked orientation, use the Display API to retrieve physical screen dimensions instead of MediaQuery. MediaQuery fails to receive the larger window size in compatibility modes.
  • Support Multiple Inputs: Implement support for basic mice, trackpads, and keyboard shortcuts. Ensure touch targets are appropriately sized and keyboard navigation is accessible.

Workflow: Constructing an Adaptive Layout

Follow this workflow to implement a layout that adapts to the available BoxConstraints.

Task Progress:

  • Identify the target widget that requires adaptive behavior.
  • Wrap the widget tree in a LayoutBuilder.
  • Extract the constraints.maxWidth from the builder callback.
  • Define an adaptive breakpoint (e.g., largeScreenMinWidth = 600).
  • If maxWidth > largeScreenMinWidth: Return a large-screen layout (e.g., a Row placing a navigation sidebar and content area side-by-side).
  • If maxWidth <= largeScreenMinWidth: Return a small-screen layout (e.g., a Column or standard navigation-style approach).
  • Run validator -> resize the application window -> review layout transitions -> fix overflow errors.

Workflow: Optimizing for Large Screens

Follow this workflow to prevent UI elements from stretching unnaturally on large displays.

Task Progress:

  • Identify full-width components (e.g., ListView, text blocks, forms).
  • If optimizing a list: Convert ListView.builder to GridView.builder using SliverGridDelegateWithMaxCrossAxisExtent to automatically adjust column counts based on window size.
  • If optimizing a form or text block: Wrap the component in a ConstrainedBox.
  • Apply BoxConstraints(maxWidth: [optimal_width]) to the ConstrainedBox.
  • Wrap the ConstrainedBox in a Center widget to keep the constrained content centered on large screens.
  • Run validator -> test on desktop/tablet target -> review horizontal stretching -> adjust maxWidth or grid extents.

Examples

Adaptive Layout using LayoutBuilder

Demonstrates switching between a mobile and desktop layout based on available width.

dart
import 'package:flutter/material.dart';
const double largeScreenMinWidth = 600.0;
class AdaptiveLayout extends StatelessWidget {  const AdaptiveLayout({super.key});
  @override  Widget build(BuildContext context) {    return LayoutBuilder(      builder: (context, constraints) {        if (constraints.maxWidth > largeScreenMinWidth) {          return _buildLargeScreenLayout();        } else {          return _buildSmallScreenLayout();        }      },    );  }
  Widget _buildLargeScreenLayout() {    return Row(      children: [        const SizedBox(width: 250, child: Placeholder(color: Colors.blue)),        const VerticalDivider(width: 1),        Expanded(child: const Placeholder(color: Colors.green)),      ],    );  }
  Widget _buildSmallScreenLayout() {    return const Placeholder(color: Colors.green);  }}

Constraining Width on Large Screens

Demonstrates preventing a widget from consuming all horizontal space.

dart
import 'package:flutter/material.dart';
class ConstrainedContent extends StatelessWidget {  const ConstrainedContent({super.key});
  @override  Widget build(BuildContext context) {    return Scaffold(      body: Center(        child: ConstrainedBox(          constraints: const BoxConstraints(            maxWidth: 800.0, // Maximum width for readability          ),          child: ListView.builder(            itemCount: 50,            itemBuilder: (context, index) {              return ListTile(                title: Text('Item $index'),              );            },          ),        ),      ),    );  }}

來源與署名

來源:flutter/agent-plugins位於skills/flutter-build-responsive-layout提交0ef3972

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架