在 Flutter 中,Scaffold 是构建 Material Design 风格页面的核心组件,它提供了基础的页面结构框架,可以快速集成常见的 UI 元素(如 AppBar、抽屉菜单、悬浮按钮等)。以下是 Scaffold 的详细用法和常见配置:
一、Scaffold 的基本结构
Scaffold(
appBar: AppBar(...),
body: Container(...),
floatingActionButton: FloatingActionButton(...),
drawer: Drawer(...),
bottomNavigationBar: BottomNavigationBar(...),
// 其他参数...
);
二、核心属性和用法
1. appBar(顶部导航栏)
- 类型:
AppBar - 用途:显示标题、导航按钮、操作菜单等。
- 常用配置:
appBar: AppBar( title: Text('首页'), leading: IconButton(icon: Icon(Icons.menu), onPressed: () {}), actions: [ IconButton(icon: Icon(Icons.search), onPressed: () {}), ], backgroundColor: Colors.blue, ),
2. body(页面主体内容)
- 类型:
Widget - 用途:页面的主要内容区域。
- 示例:
body: Center( child: Text('Hello Flutter!'), ),
3. floatingActionButton(悬浮按钮)
- 类型:
FloatingActionButton - 用途:显示一个悬浮的圆形操作按钮。
- 位置调整:
floatingActionButton: FloatingActionButton( onPressed: () {}, child: Icon(Icons.add), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, // 位置配置
4. drawer(左侧抽屉菜单)
- 类型:
Drawer - 用途:从左侧滑出的导航菜单。
- 示例:
drawer: Drawer( child: ListView( children: [ DrawerHeader(child: Text('Header')), ListTile(title: Text('Item 1')), ListTile(title: Text('Item 2')), ], ), ),
5. endDrawer(右侧抽屉菜单)
- 类型:
Drawer - 用法与
drawer类似,但从右侧滑出。
6. bottomNavigationBar(底部导航栏)
- 类型:
BottomNavigationBar - 用途:底部导航栏,支持多个标签切换。
- 示例:
bottomNavigationBar: BottomNavigationBar( items: [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.settings), label: '设置'), ], currentIndex: _selectedIndex, onTap: (index) => setState(() => _selectedIndex = index), ),
7. backgroundColor(背景颜色)
- 类型:
Color - 用途:设置整个 Scaffold 的背景颜色。
- 示例:
backgroundColor: Colors.grey[200],
8. resizeToAvoidBottomInset(避免键盘遮挡)
- 类型:
bool - 用途:当键盘弹出时是否自动调整布局(默认
true)。
三、高级用法
1. 嵌套 Scaffold
- 可以在页面中嵌套多个
Scaffold,但需要注意上下文(如ScaffoldMessenger用于显示 SnackBar):Scaffold( body: Scaffold( appBar: AppBar(title: Text('嵌套 Scaffold')), ), );
2. 自定义底部栏
- 通过
bottomSheet属性实现自定义底部栏:
bottomSheet: Container(
height: 50,
color: Colors.blue,
child: Center(child: Text('Custom Bottom Sheet')),
),
bottomSheet一般和bottomNavigationBar不会同时出现,当bottomNavigationBar不能满足业务需求的时候,可以考虑使用bootomSheet来自定义一个底部栏。当然,两个同时出现也不会有什么问题。少部分场景可能需要二级导航栏的时候,也是可以用的。
3. 控制抽屉菜单
- 手动打开/关闭抽屉:
// 打开左侧抽屉 Scaffold.of(context).openDrawer(); // 打开右侧抽屉 Scaffold.of(context).openEndDrawer();
四、完整示例代码
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scaffold 示例'),
actions: [IconButton(icon: Icon(Icons.share), onPressed: () {})],
),
drawer: Drawer(
child: ListView(
children: [
GestureDetector(
onTap: (){
scaffoldKey.currentState?.closeDrawer(); //关闭左侧菜单栏
},
child: ListTile(title: Text('菜单项1')),
),
GestureDetector(
onTap: (){
scaffoldKey.currentState?.closeDrawer(); //关闭左侧菜单栏
},
child: ListTile(title: Text('菜单项2')),
),
],
),
),
body: Center(
child: Text('当前页面: $_selectedIndex'),
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: (index) => setState(() => _selectedIndex = index),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
);
}
}
五、注意事项
- 避免过度嵌套:Scaffold 通常作为页面的根组件,避免多层嵌套导致性能问题。
- 上下文问题:在 Scaffold 的子组件中调用
Scaffold.of(context)时,确保context正确。 - 键盘处理:当页面有输入框时,
resizeToAvoidBottomInset会自动调整布局防止键盘遮挡。
通过灵活组合 Scaffold 的各个属性,可以快速构建出符合 Material Design 规范的复杂页面结构。