- 文章信息 - Author: Jack Lee (jcLee95)
Visit me at: https://jclee95.blog.csdn.net
Email: 291148484@163.com.
Shenzhen Chine
Address of this article:https://blog.csdn.net/qq_28550263/article/details/xxxxxx
【介绍】:本文带你阅读 Flutter Demo,并全面解析其中涉及的相关知识点。
【提示】:效果演示在本文末尾
目 录
1. 概述 2. 第一部分:Material 导入 和主函数 2.1 看代码
这部分代码为:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
2.2 导入 Material
import 'package:flutter/material.dart';
这行代码导入了 Flutter 的 Material 库,它提供了大量的预定义 UI 组件和样式,使我们能够快速构建具有 Material Design 风格的应用程序。
2.2 main函数程序入口
void main() {
runApp(const MyApp());
}
main() 函数是 Dart 程序的入口点。在这个函数中,我们调用了 runApp() 方法并传递了一个 MyApp 类的常量实例。runApp
() 方法将传入的 Widget(组件)作为应用程序的根 Widget,并开始构建 Widget 树。在这里,我们将自定义的 MyApp Widget 作为应用程序的根 Widget。
runApp 函数
runApp()
函数是 Flutter 应用程序的启动函数。它接受一个 Widget 参数,作为应用程序的根 Widget。当调用 runApp()
函数时,Flutter 会将传入的 Widget 附加到渲染树中,并开始构建和显示整个 Widget 树。这个函数通常在应用程序的 main()
函数中调用,以便在应用程序启动时执行。
runApp()
函数的相关信息如下:
项目 | 描述 |
---|---|
参数 | runApp() 函数接受一个 Widget 参数,这个 Widget 通常是一个自定义的根 Widget,它包含了应用程序的整个 UI 结构。 |
功能 | runApp() 函数将传入的 Widget 作为根 Widget,附加到渲染树中。接着,Flutter 开始构建和显示整个 Widget 树,从根 Widget 开始,逐级向下构建各个子 Widget。 |
用法 | runApp() 函数通常在应用程序的 main() 函数中调用,以便在应用程序启动时执行。 |
例如:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Hello World')),
body: Center(child: Text('Welcome to my app!')),
),
);
}
}
在这个示例中,runApp()
函数在 main()
函数中被调用,并传入了一个 MyApp
类的实例。MyApp
是一个自定义的根 Widget,包含了整个应用程序的 UI 结构。
3. 第二部分:无状态组件 MyApp 类
3.1 看代码
这部分代码为:
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 这个 widget 是您应用程序的根。
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// 这是您应用程序的主题。
//
// 尝试一下:尝试使用 "flutter run" 运行您的应用程序。您会看到
// 应用程序具有蓝色的工具栏。然后,在不退出应用的情况下,
// 尝试将下面 colorScheme 中的 seedColor 更改为 Colors.green,
// 然后调用 "hot reload"(保存更改或按下 Flutter 支持的 IDE 中的 "hot
// reload" 按钮,或者如果您使用了命令行启动应用程序,则按 "r")。
//
// 注意计数器没有重置为零;应用程序状态在重新加载期间不会丢失。
// 要重置状态,请使用热重启代替。
//
// 这对代码也同样适用,而不仅仅是值:大多数代码更改都可以
// 通过热重载进行测试。
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter演示主页'),
);
}
}
3.2 继承 StatelessWidget 类
以下是对 Flutter 代码的解析:
class MyApp extends StatelessWidget {
const MyApp({super.key});
这段代码定义了一个名为 MyApp
的类,该类继承自 StatelessWidget
。StatelessWidget
是一个不可变的 Widget,它描述了应用程序的一部分 UI。MyApp
类有一个构造函数,它接受一个名为 key
的可选参数,并将其传递给父类 StatelessWidget
的构造函数。
3.3 StatelessWidget 类的 build 方法
Widget build(BuildContext context) {
这里我们覆盖了 StatelessWidget
类中的 build
方法。build
方法是一个返回 Widget
的函数,它接受一个 BuildContext
参数。BuildContext
是一个表示当前 Widget 在 Widget 树中的位置的对象。当 Flutter 需要构建这个 Widget 时,会调用这个方法。
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter演示主页'),
);
}
}
在 build
方法中,我们返回一个 MaterialApp
Widget。MaterialApp
是一个方便的顶级 Widget,它包含了许多 Material Design 风格的应用程序所需的基本组件。它接受以下参数:
-
title
:应用程序的标题,通常用于任务管理器或窗口标题。 -
theme
:应用程序的主题数据。在这里,我们使用ThemeData
类来创建一个自定义主题,其中:colorScheme
:使用ColorScheme.fromSeed()
方法生成一个基于Colors.deepPurple
的颜色方案。useMaterial3
:设置为true
,以便在应用程序中使用 Material 3 风格。
-
home
:应用程序的主屏幕 Widget。在这里,我们创建了一个名为MyHomePage
的自定义 Widget,并设置了其标题为 “Flutter演示主页”。
在 StatelessWidget
类中,build
方法是一个描述由该 Widget 表示的用户界面部分的方法。它通过构建其他 Widget 的组合来描述用户界面,这些 Widget 以更具体的方式描述用户界面。构建过程会递归进行,直到用户界面的描述完全具体化。框架会在将此 Widget 插入到给定的 BuildContext
中以及此 Widget 的依赖关系发生更改(例如,此 Widget 引用的 InheritedWidget
发生更改)时调用此方法。
在实践中,build
方法的主要作用是返回一个新的 Widget,该 Widget 描述了应用程序的用户界面。通常,这个方法会包含一些条件逻辑,以便根据传入的参数或外部状态生成不同的 Widget。这使得 StatelessWidget
成为一个非常灵活的构建块,可以用来创建复杂的用户界面。
Widget build(BuildContext context) {
// 在此处返回一个新的 Widget,描述应用程序的用户界面。
}
3.4 Dart 语言中的 @override 注解
关于 dart 语言的注解,可以参考博文《Dart笔记:Dart语言中的注解》
@override
注解用于表示子类的方法覆盖了父类的方法。这有助于在重构代码时确保正确地覆盖了父类方法。如果没有正确覆盖,Dart分析器会发出警告。
3.5 MaterialApp 顶层组件
MaterialApp
是一个方便的顶级 Widget,它封装了一些 Material Design 风格的应用程序所需的基本组件,如导航、主题和路由。它继承自 WidgetsApp
类,提供了一些与 Material Design 相关的功能。以下是 MaterialApp
的一些主要属性及其解释:
属性 | 类型 | 默认值 | 描述 | 参考链接 |
---|---|---|---|---|
title | String | ‘’ | 应用程序的标题,将显示在操作系统的任务切换器中。 | MaterialApp.title |
home | Widget | null | 应用程序的默认页面,通常是显示在应用程序启动时的第一个页面。 | MaterialApp.home |
theme | ThemeData | null | 应用程序的全局主题。您可以定义自己的 ThemeData 对象,以自定义应用程序的颜色、字体、按钮样式等。 | MaterialApp.theme |
color | Color | null | 应用程序在操作系统界面中使用的主色,如 Android 的任务切换器。如果未设置,则使用 ThemeData.primaryColor 。 | MaterialApp.color |
routes | Map<String, WidgetBuilder> | null | 应用程序的路由表,用于定义应用程序中的页面导航。路由表是一个字符串到 WidgetBuilder 的映射,其中字符串表示路由名称,WidgetBuilder 是一个接受 BuildContext 并返回 Widget 的函数。 | MaterialApp.routes |
initialRoute | String | null | 应用程序的初始路由名称。如果设置了 initialRoute ,则在启动时将导航至该路由,而不是使用 home 属性。 | MaterialApp.initialRoute |
onGenerateRoute | RouteFactory | null | 一个回调函数,用于根据给定的路由设置生成路由。如果您需要在应用程序中使用动态路由或参数化路由,可以使用此属性。 | MaterialApp.onGenerateRoute |
onUnknownRoute | RouteFactory | null | 一个回调函数,用于处理未在 routes 表中找到的路由。通常用于显示一个 “404 页面未找到” 的错误页面。 | MaterialApp.onUnknownRoute |
navigatorKey | GlobalKey<NavigatorState> | null | 与应用程序的 Navigator 相关联的全局键。如果您需要从应用程序的其他部分访问 Navigator ,可以使用此属性。 | MaterialApp.navigatorKey |
builder | TransitionBuilder | null | 一个回调函数,可以在应用程序的路由之上插入一个 Widget。这对于需要在整个应用程序范围内显示的 Widget(如对话框或覆盖层)非常有用。 | MaterialApp.builder |
localizationsDelegates | List<LocalizationsDelegate<dynamic>> | null | 一个 LocalizationsDelegate 列表,用于设置应用程序的本地化资源。 | MaterialApp.localizationsDelegates |
supportedLocales | List<Locale> | null | 应用程序支持的地区列表。 | MaterialApp.supportedLocales |
以下是一个简单的 MaterialApp
示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(),
);
}
}
3.6 色彩方案:ColorScheme 类
官方文档位于:https://api.flutter.dev/flutter/material/ColorScheme-class.html
ColorScheme
是一个包含一组用于描述应用程序颜色的属性的类。它是一个不可变的对象,用于定义应用程序中使用的颜色。在 Material Design 中,ColorScheme 用于定义主题的颜色。以下是 ColorScheme
的一些常用属性:
属性 | 描述 |
---|---|
primary | 应用程序主要部分的背景颜色。例如,工具栏和浮动操作按钮。 |
primaryVariant | 主要颜色的较暗版本。 |
secondary | 应用程序次要部分的背景颜色。例如,选项卡栏。 |
secondaryVariant | 次要颜色的较暗版本。 |
surface | 卡片和抽屉等表面元素的背景颜色。 |
background | 应用程序背景颜色。 |
error | 错误状态和异常情况下使用的颜色。 |
onPrimary | 显示在主要颜色上的文本和图标的颜色。 |
onSecondary | 显示在次要颜色上的文本和图标的颜色。 |
onSurface | 显示在表面颜色上的文本和图标的颜色。 |
onBackground | 显示在背景颜色上的文本和图标的颜色。 |
onError | 显示在错误颜色上的文本和图标的颜色。 |
brightness | 应用程序的整体亮度。它是一个 Brightness 枚举,可以是 Brightness.light 或 Brightness.dark 。 |
例如:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'ColorScheme Demo',
theme: ThemeData(
colorScheme: ColorScheme(
primary: Colors.blue,
primaryVariant: Colors.blue[700],
secondary: Colors.orange,
secondaryVariant: Colors.orange[700],
surface: Colors.white,
background: Colors.white,
error: Colors.red,
onPrimary: Colors.white,
onSecondary: Colors.white,
onSurface: Colors.black,
onBackground: Colors.black,
onError: Colors.white,
brightness: Brightness.light,
),
),
home: MyHomePage(),
);
}
}
4. 第三部分:有状态组件 MyHomePage
4.1 看代码
这部分代码如下:
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// 这个 widget 是你的应用程序的主页。它是有状态的,这意味着它有一个 State 对象
// (在下面定义),其中包含影响其外观的字段。
// 这个类是 state 的配置。它保存了由父级(在本例中是 App widget)提供的值
// (在本例中是标题),并被 State 的 build 方法使用。Widget 子类中的字段总是
// 被标记为 "final"。
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
4.2 继承于 StatefulWidget 类
这段代码定义了一个名为 MyHomePage
的 StatefulWidget 类,表示该类为一个 有状态组件。
class MyHomePage extends StatefulWidget {
这一行定义了一个名为 MyHomePage
的类,它继承自 StatefulWidget
。StatefulWidget
是 Flutter 中的一种 Widget,它可以在其生命周期内保持可变状态。
const MyHomePage({super.key, required this.title});
这是 MyHomePage
类的构造函数。它接受两个参数:
super.key
:这是传递给父类(StatefulWidget
)构造函数的可选key
参数。key
参数用于控制框架如何将新的 Widget 与先前的 Widget 关联起来。通常情况下,您不需要处理key
,除非您在处理有状态的 Widget 或需要对 Widget 树进行优化。required this.title
:这是一个必需的title
参数,它是一个字符串。required
关键字表示调用构造函数时必须提供此参数。this.title
表示将传入的参数值赋给类的title
属性。
4.3 title 属性
final String title;
这一行定义了一个名为 title
的不可变字符串属性。final
关键字表示一旦初始化后,这个属性将无法更改。
4.4 createState 方法
State<MyHomePage> createState() => _MyHomePageState();
这是 createState
方法,它是 StatefulWidget
类的必需方法。此方法用于创建与此 StatefulWidget 实例关联的状态对象。@override
关键字表示我们在这里重写了父类的方法。State<MyHomePage> createState() => _MyHomePageState();
表示我们将返回一个名为 _MyHomePageState
的新状态对象。
createState
方法是 StatefulWidget
类的核心方法,它用于创建与 StatefulWidget 实例关联的状态对象。当框架需要构建 StatefulWidget 时,它会调用此方法以创建一个新的状态对象。这个状态对象将在 StatefulWidget 的整个生命周期中保持与之关联。
@override
:这是一个元数据注解,表示我们将重写父类StatefulWidget
的方法。在这种情况下,我们重写createState
方法。这样做的目的是为了提供一个自定义的状态对象,以便在构建我们的MyHomePage
StatefulWidget 时使用。State<MyHomePage> createState()
:这是我们重写的方法。方法的返回类型是State<MyHomePage>
,表示我们将返回一个与MyHomePage
类型关联的状态对象。这个状态对象将负责管理与MyHomePage
实例相关的状态。=> _MyHomePageState();
:这是一个简化的函数体,等同于{ return _MyHomePageState(); }
。箭头函数表示我们将创建一个名为_MyHomePageState
的新状态对象,并将其作为结果返回。
要了解 createState
方法的重要性,我们需要了解 StatefulWidget 的工作原理。StatefulWidget 是一个具有可变状态的 Widget。当 StatefulWidget 的状态发生变化时,框架会重新构建 Widget 树以反映这些更改。为了实现这一点,框架需要知道如何创建与 StatefulWidget 实例关联的状态对象。这就是 createState
方法的作用:告诉框架如何创建状态对象。
在实际应用中,createState
方法通常会返回一个自定义的 State
子类,该子类包含了与 StatefulWidget 实例关联的状态数据和逻辑。这使得 StatefulWidget 可以在其生命周期内保持状态,从而实现动态 UI、响应事件和执行其他与状态相关的操作。
5. 状态类 _MyHomePageState
5.1 看代码
在上一节中,定义了一个名为 MyHomePage 的 有状态组件(继承于StatefulWidget 类)。其 createState
方法中使用了一个名为 _MyHomePageState 的 状态类,该类将在创建 MyHomePage 实例时与其关联。
_MyHomePageState 类是一个自定义的 State 子类,负责管理与 MyHomePage 实例相关的状态。它包含一个 _counter
属性,表示按下按钮的次数,以及一个 _incrementCounter
方法,用于更新 _counter
的值。它还实现了 build
方法,用于构建与 MyHomePage
实例关联的 UI。
_MyHomePageState 类的代码如下:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// 这个对 setState 的调用告诉 Flutter 框架,这个 State 中的某些内容已经发生了变化,
// 这将导致它重新运行下面的 build 方法,以便显示可以反映更新后的值。如果我们更改了
// _counter 而没有调用 setState(),那么 build 方法将不会再次被调用,因此什么都不会发生。
_counter++;
});
}
Widget build(BuildContext context) {
// 每次调用 setState 时,例如上面的 _incrementCounter 方法所做的,
// 都会重新运行此方法。
// Flutter 框架已经过优化,以使得重新运行 build 方法变得更快,
// 因此你可以重建任何需要更新的内容,而不是必须单独更改 widget 实例。
return Scaffold(
appBar: AppBar(
// 尝试一下:尝试将这里的颜色更改为特定颜色(例如 Colors.amber?),
// 然后触发热重载以查看 AppBar 的颜色变化,而其他颜色保持不变。
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// 这里我们从由 App.build 方法创建的 MyHomePage 对象中获取值,
// 并将其用于设置我们的 appbar 标题。
title: Text(widget.title),
),
body: Center(
// Center 是一个布局 widget。它接受一个子 widget,并将其定位
// 在父 widget 的中央。
child: Column(
// Column 也是一个布局 widget。它接受一组子 widget,并垂直排列它们。
// 默认情况下,它会自动调整自身尺寸以适应其子 widget 水平方向的尺寸,
// 并尽量与其父 widget 一样高。
// Column 具有各种属性来控制它如何调整自身尺寸以及如何定位其子 widget。
// 在这里,我们使用 mainAxisAlignment 将子 widget 垂直居中;主轴在这里
// 是垂直轴,因为 Column 是垂直的(交叉轴将是水平的)。
// 尝试一下:调用 "debug painting"(在 IDE 中选择 "Toggle Debug Paint"
//操作,或者在控制台中按 "p"),以查看每个 widget 的线框。
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'你已经按了这个按钮很多次了:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // 这个尾随逗号使得自动格式化在构建方法中更加美观。
);
}
}
_MyHomePageState 类应该继承自 State 类,并实现 build
方法以构建与 MyHomePage 实例关联的 UI。
5.2 State 类
State 类的官方文档地址为:https://api.flutter.dev/flutter/widgets/State-class.html
在Flutter中,State
类是与StatefulWidget
相关的一个重要概念。State
对象存储了一个StatefulWidget
的可变状态。当状态改变时,State
对象会通知Flutter框架重建UI。
State
类的生命周期包括以下几个阶段:
阶段 | 描述 |
---|---|
created | 当State 对象被创建时,State.initState 方法会被调用。 |
initialized | 当State 对象被创建,但还没有准备构建时,State.didChangeDependencies 在这个时候会被调用。 |
ready | State 对象已经准备好了构建,State.dispose 没有被调用的时候。 |
defunct | State.dispose 被调用后,State 对象不能够被构建。 |
要改变State
对象的状态,可以使用setState
方法。setState
方法接受一个回调函数,该函数对状态进行修改。当回调函数执行完毕后,Flutter框架将安排重建UI。
下面是一个简单的例子,演示了如何使用State
类和setState
方法:
class Counter extends StatefulWidget {
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _incrementCounter() {
setState(() {
_count = _count + 1;
});
}
Widget build(BuildContext context) {
return Column(
children: [
Text('You have pushed the button this many times:'),
Text('$_count', style: Theme.of(context).textTheme.headline4),
ElevatedButton(
onPressed: _incrementCounter,
child: Text('Increment Counter'),
),
],
);
}
}
在这个例子中,_CounterState
类维护了一个名为_count
的状态。当用户点击按钮时,_incrementCounter
方法会被调用,使用setState
方法更新_count
的值。这将触发Flutter框架重建UI,以显示更新后的计数值。
5.3 提升按钮:ElevatedButton组件
这是 Flutter 提供的诸多按钮中的一种,其前身为 凸起按钮:RaisedButton组件,RaisedButton现在已经被废弃,官方推荐使用 ElevatedButton 替代。
关于 Flutter 的各种按钮类组件及其详细用法的更多介绍,请参考博文《Flutter 组件(三)按钮类组件》:https://blog.csdn.net/qq_28550263/article/details/131387856
F. 附录
F.1 Flutter Demo 完整源代码
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 这个 widget 是您应用程序的根。
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// 这是您应用程序的主题。
//
// 尝试一下:尝试使用 "flutter run" 运行您的应用程序。您会看到
// 应用程序具有蓝色的工具栏。然后,在不退出应用的情况下,
// 尝试将下面 colorScheme 中的 seedColor 更改为 Colors.green,
// 然后调用 "hot reload"(保存更改或按下 Flutter 支持的 IDE 中的 "hot
// reload" 按钮,或者如果您使用了命令行启动应用程序,则按 "r")。
//
// 注意计数器没有重置为零;应用程序状态在重新加载期间不会丢失。
// 要重置状态,请使用热重启代替。
//
// 这对代码也同样适用,而不仅仅是值:大多数代码更改都可以
// 通过热重载进行测试。
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter演示主页'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// 这个 widget 是你的应用程序的主页。它是有状态的,这意味着它有一个 State 对象
// (在下面定义),其中包含影响其外观的字段。
// 这个类是 state 的配置。它保存了由父级(在本例中是 App widget)提供的值
// (在本例中是标题),并被 State 的 build 方法使用。Widget 子类中的字段总是
// 被标记为 "final"。
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// 这个对 setState 的调用告诉 Flutter 框架,这个 State 中的某些内容已经发生了变化,
// 这将导致它重新运行下面的 build 方法,以便显示可以反映更新后的值。如果我们更改了
// _counter 而没有调用 setState(),那么 build 方法将不会再次被调用,因此什么都不会发生。
_counter++;
});
}
Widget build(BuildContext context) {
// 每次调用 setState 时,例如上面的 _incrementCounter 方法所做的,
// 都会重新运行此方法。
// Flutter 框架已经过优化,以使得重新运行 build 方法变得更快,
// 因此你可以重建任何需要更新的内容,而不是必须单独更改 widget 实例。
return Scaffold(
appBar: AppBar(
// 尝试一下:尝试将这里的颜色更改为特定颜色(例如 Colors.amber?),
// 然后触发热重载以查看 AppBar 的颜色变化,而其他颜色保持不变。
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// 这里我们从由 App.build 方法创建的 MyHomePage 对象中获取值,
// 并将其用于设置我们的 appbar 标题。
title: Text(widget.title),
),
body: Center(
// Center 是一个布局 widget。它接受一个子 widget,并将其定位
// 在父 widget 的中央。
child: Column(
// Column 也是一个布局 widget。它接受一组子 widget,并垂直排列它们。
// 默认情况下,它会自动调整自身尺寸以适应其子 widget 水平方向的尺寸,
// 并尽量与其父 widget 一样高。
// Column 具有各种属性来控制它如何调整自身尺寸以及如何定位其子 widget。
// 在这里,我们使用 mainAxisAlignment 将子 widget 垂直居中;主轴在这里
// 是垂直轴,因为 Column 是垂直的(交叉轴将是水平的)。
// 尝试一下:调用 "debug painting"(在 IDE 中选择 "Toggle Debug Paint"
//操作,或者在控制台中按 "p"),以查看每个 widget 的线框。
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'你已经按了这个按钮很多次了:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // 这个尾随逗号使得自动格式化在构建方法中更加美观。
);
}
}