LayoutBuilder 與自適應版面配置
了解如何使用 LayoutBuilder 元件。
了解如何建立能適應不同螢幕寬度的版面配置。
你將完成的事項
Steps
1
簡介
簡介
現代應用程式需要在各種尺寸的螢幕上都能良好運作。 在本頁中,你將學習如何建立能適應不同螢幕寬度的版面配置。 此應用程式在大螢幕上會顯示側邊欄, 在小螢幕上則使用以導覽為基礎的使用者介面。 具體而言,此應用程式處理兩種螢幕尺寸:
- 大螢幕(平板電腦、桌上型電腦): 並排顯示聯絡人群組與聯絡人詳細資料。
- 小螢幕(手機): 使用導覽在聯絡人群組與詳細資料之間切換。
2
建立聯絡人群組頁面
建立聯絡人群組頁面
首先,為你的聯絡人群組畫面建立 ContactGroupsPage 元件 (Widget) 的基本結構。
建立 lib/screens/contact_groups.dart 並加入以下基本結構:
import 'package:flutter/cupertino.dart';
class ContactGroupsPage extends StatelessWidget {
const ContactGroupsPage({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoPageScaffold(
backgroundColor: CupertinoColors.extraLightBackgroundGray,
child: Center(child: Text('Contact Groups will go here')),
);
}
}
3
建立聯絡人頁面
建立聯絡人頁面
同樣地,建立 lib/screens/contacts.dart,
以便日後顯示個別聯絡人:
import 'package:flutter/cupertino.dart';
class ContactListsPage extends StatelessWidget {
const ContactListsPage({super.key, required this.listId});
final int listId;
@override
Widget build(BuildContext context) {
return const CupertinoPageScaffold(
backgroundColor: CupertinoColors.extraLightBackgroundGray,
child: Center(child: Text('Lists of contacts will go here')),
);
}
}
ContaactsListPage 元件與 ContactGroupsPage 元件是
實作自適應版面配置元件所需的佔位頁面,
你接下來將進行這項實作。
4
建置自適應版面配置的基礎
建置自適應版面配置的基礎
建立 lib/screens/adaptive_layout.dart
並從以下基本結構開始:
import 'package:flutter/cupertino.dart';
import 'contact_groups.dart';
class AdaptiveLayout extends StatefulWidget {
const AdaptiveLayout({super.key});
@override
State<AdaptiveLayout> createState() => _AdaptiveLayoutState();
}
class _AdaptiveLayoutState extends State<AdaptiveLayout> {
@override
Widget build(BuildContext context) {
return const ContactGroupsPage(); // Temporary placeholder
}
}
這是一個 StatefulWidget,因為自適應版面配置最終
需要管理目前選取的聯絡人群組。
接下來,將螢幕大小偵測邏輯加入 lib/screens/adaptive_layout.dart:
import 'package:flutter/cupertino.dart';
import 'contact_groups.dart';
const largeScreenMinWidth = 600;
class AdaptiveLayout extends StatefulWidget {
const AdaptiveLayout({super.key});
@override
State<AdaptiveLayout> createState() => _AdaptiveLayoutState();
}
class _AdaptiveLayoutState extends State<AdaptiveLayout> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final isLargeScreen = constraints.maxWidth > largeScreenMinWidth;
if (isLargeScreen) {
return const Text('Large screen layout'); // Temporary
} else {
return const ContactGroupsPage();
}
},
);
}
}
LayoutBuilder 元件提供了父元件尺寸限制的相關資訊。
在 builder 回呼(callback)中,你會收到一個 BoxConstraints 物件,
告訴你可用的最大寬度與高度。
透過檢查 constraints.maxWidth > largeScreenMinWidth,
你可以決定要顯示哪種版面配置。
600 像素的閾值是常見的斷點,
用來區分手機尺寸與平板電腦尺寸的螢幕。
5
更新主應用程式
更新主應用程式
更新 main.dart 以使用自適應版面配置,
讓你可以看到變更效果:
import 'package:flutter/cupertino.dart';
import 'data/contact_group.dart';
import 'screens/adaptive_layout.dart';
final contactGroupsModel = ContactGroupsModel();
void main() {
runApp(const RolodexApp());
}
class RolodexApp extends StatelessWidget {
const RolodexApp({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoApp(
title: 'Rolodex',
theme: CupertinoThemeData(
barBackgroundColor: CupertinoDynamicColor.withBrightness(
color: Color(0xFFF9F9F9),
darkColor: Color(0xFF1D1D1D),
),
),
home: AdaptiveLayout(),
);
}
}
如果你在 Chrome 中執行,可以調整瀏覽器視窗大小來 觀察版面配置的變化。
6
加入清單選取功能
加入清單選取功能
大螢幕版面配置需要追蹤目前選取的聯絡人群組。
使用以下程式碼更新 lib/screens/adaptive_layout.dart 中的狀態物件:
import 'package:flutter/cupertino.dart';
import 'contact_groups.dart';
const largeScreenMinWidth = 600;
class AdaptiveLayout extends StatefulWidget {
const AdaptiveLayout({super.key});
@override
State<AdaptiveLayout> createState() => _AdaptiveLayoutState();
}
class _AdaptiveLayoutState extends State<AdaptiveLayout> {
int selectedListId = 0;
void _onContactListSelected(int listId) {
setState(() {
selectedListId = listId;
});
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final isLargeScreen = constraints.maxWidth > largeScreenMinWidth;
if (isLargeScreen) {
return const Text('Large screen layout');
} else {
return const ContactGroupsPage();
}
},
);
}
}
selectedListId 變數追蹤目前選取的聯絡人群組,
而 _onContactListSelected 則在使用者做出選擇時更新此值。
7
建置大螢幕版面配置
建置大螢幕版面配置
現在,在 lib/screens/adaptive_layout.dart 中實作大螢幕的並排版面配置。
首先,將暫時的文字替換為包含正確版面配置的元件。
import 'package:flutter/cupertino.dart';
import 'contact_groups.dart';
const largeScreenMinWidth = 600;
class AdaptiveLayout extends StatefulWidget {
const AdaptiveLayout({super.key});
@override
State<AdaptiveLayout> createState() => _AdaptiveLayoutState();
}
class _AdaptiveLayoutState extends State<AdaptiveLayout> {
int selectedListId = 0;
void _onContactListSelected(int listId) {
setState(() {
selectedListId = listId;
});
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final isLargeScreen = constraints.maxWidth > largeScreenMinWidth;
if (isLargeScreen) {
return _buildLargeScreenLayout();
} else {
// For small screens, use the original, navigation-style approach.
return const ContactGroupsPage();
}
},
);
}
Widget _buildLargeScreenLayout() {
return const CupertinoPageScaffold(
backgroundColor: CupertinoColors.extraLightBackgroundGray,
child: SafeArea(child: Row(children: [Text('Sidebar'), Text('Details')])),
);
}
}
大螢幕版面配置使用 Row 來
並排放置側邊欄與詳細資料。
SafeArea 確保內容不會與
狀態列等系統 UI 元素重疊。
現在,設定兩個面板的大小,
並在 lib/screens/adaptive_layout.dart 中加入視覺分隔線:
Widget _buildLargeScreenLayout() {
return CupertinoPageScaffold(
backgroundColor: CupertinoColors.extraLightBackgroundGray,
child: SafeArea(
child: Row(
children: [
const SizedBox(width: 320, child: Text('Sidebar placeholder')),
Container(width: 1, color: CupertinoColors.separator),
const Expanded(child: Text('Details placeholder')),
],
),
),
);
}
此版面配置建立了以下結構:
- 固定寬度的側邊欄(320 像素),用於顯示聯絡人群組。
- 面板之間 1 像素的分隔線。
- 詳細資料面板使用
Expanded元件佔用剩餘空間。
8
測試自適應版面配置
測試自適應版面配置
熱重載你的應用程式並測試響應式行為。 如果你在 Chrome 中執行,可以調整瀏覽器視窗大小來 觀察版面配置變化:
- 寬視窗(> 600px): 並排顯示側邊欄與詳細資料的佔位文字。
- 窄視窗(< 600px): 僅顯示聯絡人群組頁面。
側邊欄與主要內容區域目前都顯示佔位文字。
在下一課中,你將實作 sliver 來填入 聯絡人清單內容。
9
回顧
回顧
你完成了什麼
以下是你在本課中建置與學習的摘要。使用 LayoutBuilder 建立響應式版面配置
LayoutBuilder 在其 builder 回呼中提供父元件的尺寸限制。 透過檢查 constraints.maxWidth, 你可以根據可用空間決定要顯示哪種版面配置。
偵測螢幕大小以選擇不同的版面配置
你使用了 600 像素的斷點來 區分手機尺寸與平板電腦尺寸的螢幕。 這個常用閾值幫助你的應用程式調整其使用者介面, 為每台裝置提供最佳體驗。
為大螢幕建置側邊欄與詳細內容的版面配置
在大螢幕上,你使用 Row 並排顯示固定寬度的側邊欄 與 Expanded 詳細資料面板。 這個經典模式在平板電腦與桌上型電腦上最大化了螢幕空間的運用。
10
自我測驗
自我測驗
自適應版面配置測驗
1 / 2-
父元件的尺寸限制,包含最大寬度與高度。
That's right!
LayoutBuilder 的 builder 接收 BoxConstraints,告訴你來自父元件的可用空間。
-
裝置的作業系統與螢幕方向。
Not quite
LayoutBuilder 提供尺寸限制,而非作業系統或方向資訊。
-
目前的主題顏色與排版。
Not quite
主題資料來自 Theme.of(context),而非 LayoutBuilder。
-
元件樹中子元件的數量。
Not quite
LayoutBuilder 提供版面配置限制,而非元件樹資訊。
-
ListView
Not quite
ListView 用於可捲動的清單,而非並排版面配置。
-
Stack
Not quite
Stack 將元件堆疊重疊,而非並排。
-
Row
That's right!
Row 水平排列其子元件,非常適合並排放置側邊欄與詳細資料面板。
-
Column
Not quite
Column 垂直排列元件,而非並排。
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.