如何使用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 主题页面 以获取练习和编程项目。