概念 | 比喻 |
---|---|
StatefulWidget | 会变魔术的电视机 |
State | 电视机的小脑袋(记信息) |
build 方法 | 电视机变身显示新画面 |
setState | 按遥控器按钮改变状态 |
Scaffold | 电视机的外壳 |
- StatefulWidget:创建一个按钮组件。
- State:保存点赞数(比如
int likes = 0
)。 - build () 方法:显示按钮和当前点赞数。
- 点击按钮时:调用
setState(() { likes++; })
。 - Flutter 自动触发:再次调用
build()
方法,更新 UI 显示新的点赞数。
Scaffold 是什么?
Scaffold 是 Flutter 提供的一个 基础页面框架,就像盖房子的 "脚手架" 一样,帮你快速搭建出一个符合 Material Design 设计规范的页面。
它提供了这些东西:
- 顶部的导航栏(AppBar)
- 中间的内容区域(body)
- 底部的导航栏(BottomNavigationBar)
- 浮动按钮(FloatingActionButton)
- 侧边栏(Drawer)
- 底部弹窗(SnackBar)
Scaffold 的常用属性
属性名 | 作用 |
---|---|
appBar |
顶部导航栏,显示标题、操作按钮(如搜索、菜单)等。 |
body |
页面的主体内容区域,可以是文本、图片、列表等任何组件。 |
floatingActionButton |
悬浮按钮,通常在右下角,用于执行主要操作(如 "添加")。 |
bottomNavigationBar |
底部导航栏,用于在不同页面 / 功能之间切换(如微信底部的 "微信、通讯录" 等)。 |
drawer |
侧边栏,从左侧滑出,通常用于显示菜单或用户信息。 |
backgroundColor |
页面背景颜色。 |
下面是一个包含 Scaffold 所有主要部分的代码:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
// 1. 顶部导航栏
appBar: AppBar(
title: const Text('Scaffold 示例'),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {},
),
],
),
// 2. 中间内容区域
body: const Center(
child: Text('这是页面的主体内容!'),
),
// 3. 悬浮按钮(右下角)
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
// 4. 底部导航栏
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: '我的',
),
],
),
// 5. 侧边栏(从左侧滑出)
drawer: Drawer(
child: ListView(
children: const [
DrawerHeader(
child: Text('侧边栏标题'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('菜单项 1'),
),
ListTile(
title: Text('菜单项 2'),
),
],
),
),
),
);
}
}
运行效果示意图
+-----------------------------------+
| <-- | Scaffold 示例 | [搜索] | ← AppBar(导航栏)
+-----------------------------------+
| |
| |
| 这是页面的主体内容! | ← body(主体内容)
| |
| |
+-----------------------------------+
| [首页] [我的] | ← BottomNavigationBar(底部导航)
+-----------------------------------+
| [+] | ← FloatingActionButton(悬浮按钮)
+-----------------------------------+
属性 | 显示位置 | 示例代码 |
---|---|---|
MaterialApp(title: ...) |
操作系统任务管理器、应用列表 | MaterialApp(title: '计数器示例') |
AppBar(title: ...) |
应用内当前页面的导航栏 | AppBar(title: Text('计数器应用')) |
完整代码
import 'package:flutter/material.dart';
void main() {
// 启动Flutter应用,运行MyApp组件
runApp(const MyApp());
}
// 应用的根组件(无状态组件)
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '计数器示例',
theme: ThemeData(
primarySwatch: Colors.blue, // 设置主题色为蓝色
),
home: const CounterPage(), // 设置首页为CounterPage
);
}
}
// 计数器页面(有状态组件)
class CounterPage extends StatefulWidget {
const CounterPage({Key? key}) : super(key: key);
@override
_CounterPageState createState() => _CounterPageState();
}
// 计数器页面的状态类
class _CounterPageState extends State<CounterPage> {
int _counter = 0; // 声明一个变量存储计数器的值,初始值为0
// 增加计数器值的方法
void _incrementCounter() {
setState(() {
// 修改状态:将_counter的值加1
// 调用setState后,Flutter会自动重新调用build()方法更新UI
_counter++;
});
}
// 减少计数器值的方法
void _decrementCounter() {
setState(() {
if (_counter > 0) {
_counter--; // 只有当计数器大于0时才减1
}
});
}
@override
Widget build(BuildContext context) {
// Scaffold是Material Design风格的页面框架
return Scaffold(
appBar: AppBar(
title: const Text('计数器应用'), // 设置导航栏标题
),
body: Center( // 将子组件居中显示
child: Column( // 垂直排列子组件
mainAxisAlignment: MainAxisAlignment.center, // 垂直方向居中对齐
children: <Widget>[
const Text(
'当前计数:',
style: TextStyle(fontSize: 20),
),
Text(
'$_counter', // 显示计数器的值
style: Theme.of(context).textTheme.headline3, // 使用主题中的大字体
),
const SizedBox(height: 20), // 添加间距
Row( // 水平排列子组件
mainAxisAlignment: MainAxisAlignment.center, // 水平方向居中对齐
children: [
ElevatedButton(
onPressed: _decrementCounter, // 点击时调用减少计数的方法
child: const Icon(Icons.remove), // 按钮图标:减号
),
const SizedBox(width: 20), // 按钮之间的间距
ElevatedButton(
onPressed: _incrementCounter, // 点击时调用增加计数的方法
child: const Icon(Icons.add), // 按钮图标:加号
),
],
),
],
),
),
);
}
}