如何使用Flutter使用VoidCallback和Function(x)在Widget之间进行通信
介绍
Flutter 项目的一个很好的范例是将你的小部件分成小的、可测试的单元,这些单元可以适应它们的上下文。
Flutter 提供 VoidCallback
和 Function(x)
(其中 x
可以是不同的类型)用于子控件和父控件之间的回调样式事件。
在本文中,您将使用回调样式的事件与 Flutter 进行小部件之间的通信。
先决条件
要阅读本文,您将需要:
- 下载并安装 Flutter。
- 下载并安装Android Studio 或 Visual Studio Code。
- 建议为您的代码编辑器安装插件: 为 Android Studio 安装了 Flutter 和 Dart 插件。 为 Visual Studio Code 安装了 Flutter 扩展。
本文已使用 Flutter v1.22.2、Android SDK v30.0.2 和 Android Studio v4.1 进行了验证。
第 1 步 — 设置项目
为 Flutter 设置好环境后,您可以运行以下命令来创建新应用程序:
flutter create flutter_widget_communication
导航到新的项目目录:
cd flutter_widget_communication
使用 flutter create
将生成一个演示应用程序,该应用程序将显示按钮被单击的次数。
您将基于生成的代码来试验回调样式事件。
第 2 步 — 将数据从父小部件传递到子小部件
您将创建一个父窗口小部件 (CounterPage
) 和一个子窗口小部件 (Count
)。 父级的 count
值将显示在子级中。
在代码编辑器中打开 main.dart
并修改它以使用 CounterPage()
:
lib/main.dart
import 'package:flutter/material.dart'; import 'counter_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Widget Communication', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: CounterPage(), ); } }
此代码将显示 CounterPage
。
创建一个新的 counter_page.dart
文件并添加以下代码行:
lib/counter_page.dart
import 'package:flutter/material.dart'; import 'count.dart'; class CounterPage extends StatefulWidget { _CounterPageState createState() => _CounterPageState(); } class _CounterPageState extends State<CounterPage> { int count = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Widget Communication")), body: Center( child: Count(count), ), ); } }
此代码会将 count
传递给子小部件。
创建一个新的 count.dart
文件并添加以下代码行:
lib/count.dart
import 'package:flutter/material.dart'; class Count extends StatelessWidget { final int count; Count(this.count); @override Widget build(BuildContext context) { return Text("$count"); } }
编译你的代码并让它在模拟器中运行:
这将在屏幕上显示 count
(当前设置为数字零)。
接下来,您将添加一个 VoidCallback
。
第 3 步 — 使用 VoidCallback
出于本教程的目的,您将需要创建一个 Button
来注册点击并通知父级 CounterPage
。
由于您不想在此处返回值,因此您需要注册一个 VoidCallback。 您还将为 Count
构造函数中的项目添加大括号,以使它们成为 命名参数 。
重新访问 count.dart
并添加 onCountSelected
:
lib/count.dart
class Count extends StatelessWidget { final int count; final VoidCallback onCountSelected; Count({ @required this.count, this.onCountSelected, }); @override Widget build(BuildContext context) { return FlatButton( child: Text("$count"), onPressed: () => onCountSelected(), ); } }
然后,重新访问 counter_page.dart
并监听 onCountSelected
回调:
lib/counter_page.dart
import 'package:flutter/material.dart'; import 'count.dart'; class CounterPage extends StatefulWidget { _CounterPageState createState() => _CounterPageState(); } class _CounterPageState extends State<CounterPage> { int count = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Widget Communication")), body: Center( child: Count( count: count, onCountSelected: () { print("Count was selected."); }, ) ), ); } }
编译您的代码并让它在模拟器中运行。 与按钮交互并观察控制台中的输出:
OutputCount was selected.
然而,此时 count
值将保持为零。
接下来,您将添加一个 Function(x)
。
第 4 步 — 使用 Function(x)
VoidCallback
对于没有预期值的回调事件很有用。 对于要将值返回给父级的场景,您将需要使用 Function(x)
。
重新访问 count.dart
并添加 Function(int)
onCountChanged
:
lib/count.dart
import 'package:flutter/material.dart'; class Count extends StatelessWidget { final int count; final VoidCallback onCountSelected; final Function(int) onCountChanged; Count({ @required this.count, @required this.onCountChanged, this.onCountSelected, }); @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ IconButton( icon: Icon(Icons.add), onPressed: () { onCountChanged(1); }, ), FlatButton( child: Text("$count"), onPressed: () => onCountSelected(), ), IconButton( icon: Icon(Icons.remove), onPressed: () { onCountChanged(-1); }, ), ], ); } }
然后,重新访问 counter_page.dart
并监听 onCountChange
回调:
lib/counter_page.dart
import 'package:flutter/material.dart'; import 'count.dart'; class CounterPage extends StatefulWidget { _CounterPageState createState() => _CounterPageState(); } class _CounterPageState extends State<CounterPage> { int count = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Widget Communication")), body: Center( child: Count( count: count, onCountSelected: () { print("Count was selected."); }, onCountChanged: (int val) { setState(() => count += val); }, ) ), ); } }
单击按钮时,更改值会从 Count
子控件传递到 CounterPage
父控件。 然后,执行val
和count
之间的加法并更新count
。
编译你的代码并让它在模拟器中运行:
与 Add (+
) 和 Remove (-
) 按钮交互,count
值应分别递增和递减。
结论
在本文中,您学习了如何使用 VoidCallback
和 Function(x)
使用回调样式的事件在 Flutter 的小部件之间进行通信。
如果您想了解有关 Flutter 的更多信息,请查看 我们的 Flutter 主题页面 以获取练习和编程项目。