如何使用 VoidCallback 和 Function(x) 在 Flutter 小工具之间进行通信

简介

将你的小部件分成小的、可测试的单元可以适应它们的环境,这是你的颤动项目的一个很好的范例。

对于子Widget和父Widget之间的回调类型的事件,Ffltter提供了VoidCallbackFunction(X)(其中x可以是不同的类型)。

在本文中,您将使用回调样式的事件在带有Ffltter的小部件之间进行通信。

前提条件

要阅读本文,您需要:

本文使用Ffltter v1.22.2、Android SDK v30.0.2和Android Studiov4.1进行了验证。

第一步-设置项目

将环境设置为颤动后,可以运行以下命令来创建新应用程序:

1flutter create flutter_widget_communication

导航到新项目目录:

1cd flutter_widget_communication

使用fltter create将生成一个演示应用程序,其中将显示按钮被点击的次数。

您将以生成的代码为基础来试验回调样式的事件。

第二步-将数据从父Widget传递给子Widget

您将创建一个父小部件(CounterPage)和子小部件(Count)。来自父对象的Count值将显示在子对象中。

在代码编辑器中打开main.dart,修改为使用CounterPage()

 1[label lib/main.dart]
 2import 'package:flutter/material.dart';
 3import 'counter_page.dart';
 4
 5void main() {
 6  runApp(MyApp());
 7}
 8
 9class MyApp extends StatelessWidget {
10  @override
11  Widget build(BuildContext context) {
12    return MaterialApp(
13      title: 'Widget Communication',
14      theme: ThemeData(
15        primarySwatch: Colors.blue,
16        visualDensity: VisualDensity.adaptivePlatformDensity,
17      ),
18      home: CounterPage(),
19    );
20  }
21}

此代码将显示CounterPage

创建一个新的count_page.dart文件,并添加以下代码行:

 1[label lib/counter_page.dart]
 2import 'package:flutter/material.dart';
 3import 'count.dart';
 4
 5class CounterPage extends StatefulWidget {
 6  _CounterPageState createState() => _CounterPageState();
 7}
 8
 9class _CounterPageState extends State<CounterPage> {
10  int count = 0;
11
12  @override
13  Widget build(BuildContext context) {
14    return Scaffold(
15      appBar: AppBar(title: Text("Widget Communication")),
16      body: Center(
17        child: Count(count),
18      ),
19    );
20  }
21}

这段代码将把`count‘传递给子小部件。

创建一个新的count t.dart文件,并添加以下代码行:

 1[label lib/count.dart]
 2import 'package:flutter/material.dart';
 3
 4class Count extends StatelessWidget {
 5  final int count;
 6
 7  Count(this.count);
 8
 9  @override
10  Widget build(BuildContext context) {
11    return Text("$count");
12  }
13}

编译代码并让其在模拟器中运行:

显示zero计数的颤动应用程序的屏幕截图

这将在屏幕上显示Count(当前设置为数字零)。

接下来,您将添加一个VoidCallback

第三步-使用VoidCallback

出于本教程的目的,您需要创建一个Button,它将注册点击并通知父CounterPage

因为您不想在这里返回值,所以需要注册_VoidCallback。您还将向Count构造函数中的项添加大括号,使其成为_命名参数

重新访问Count.dart,添加onCountSelected

 1[label lib/count.dart]
 2class Count extends StatelessWidget {
 3  final int count;
 4  final VoidCallback onCountSelected;
 5
 6  Count({
 7    @required this.count,
 8    this.onCountSelected,
 9  });
10
11  @override
12  Widget build(BuildContext context) {
13    return FlatButton(
14      child: Text("$count"),
15      onPressed: () => onCountSelected(),
16    );
17  }
18}

然后重新访问count_page.dart,监听onCountSelected回调:

 1[label lib/counter_page.dart]
 2import 'package:flutter/material.dart';
 3import 'count.dart';
 4
 5class CounterPage extends StatefulWidget {
 6  _CounterPageState createState() => _CounterPageState();
 7}
 8
 9class _CounterPageState extends State<CounterPage> {
10  int count = 0;
11
12  @override
13  Widget build(BuildContext context) {
14    return Scaffold(
15      appBar: AppBar(title: Text("Widget Communication")),
16      body: Center(
17        child: Count(
18          count: count,
19          onCountSelected: () {
20            print("Count was selected.");
21          },
22        )
23      ),
24    );
25  }
26}

编译代码并让其在模拟器中运行。与按钮交互并在您的控制台中观察输出:

1[secondary_label Output]
2Count was selected.

但是,此时`count‘值将保持为零。

接下来,您将添加一个Function(X)

第四步-使用Function(X)

VoidCallback对于无期望值的回调事件非常有用。如果您希望将值返回给父级,则需要使用Function(X)

重新访问count.dart并添加Function(int) onCountChanged

 1[label lib/count.dart]
 2import 'package:flutter/material.dart';
 3
 4class Count extends StatelessWidget {
 5  final int count;
 6  final VoidCallback onCountSelected;
 7  final Function(int) onCountChanged;
 8
 9  Count({
10    @required this.count,
11    @required this.onCountChanged,
12    this.onCountSelected,
13  });
14
15  @override
16  Widget build(BuildContext context) {
17    return Row(
18      mainAxisAlignment: MainAxisAlignment.center,
19      children: <Widget>[
20        IconButton(
21          icon: Icon(Icons.add),
22          onPressed: () {
23            onCountChanged(1);
24          },
25        ),
26        FlatButton(
27          child: Text("$count"),
28          onPressed: () => onCountSelected(),
29        ),
30        IconButton(
31          icon: Icon(Icons.remove),
32          onPressed: () {
33            onCountChanged(-1);
34          },
35        ),
36      ],
37    );
38  }
39}

然后重新访问count_page.dart,监听onCountChange回调:

 1[label lib/counter_page.dart]
 2import 'package:flutter/material.dart';
 3import 'count.dart';
 4
 5class CounterPage extends StatefulWidget {
 6  _CounterPageState createState() => _CounterPageState();
 7}
 8
 9class _CounterPageState extends State<CounterPage> {
10  int count = 0;
11
12  @override
13  Widget build(BuildContext context) {
14    return Scaffold(
15      appBar: AppBar(title: Text("Widget Communication")),
16      body: Center(
17        child: Count(
18          count: count,
19          onCountSelected: () {
20            print("Count was selected.");
21          },
22          onCountChanged: (int val) {
23            setState(() => count += val);
24          },
25        )
26      ),
27    );
28  }
29}

当点击按钮时,变更值从Count子小部件传递到CounterPage父小部件。然后,将valCount相加,并更新Count

编译代码并让其在模拟器中运行:

颤动应用程序的屏幕截图显示一个添加按钮、一个删除按钮和计数值4

通过添加 (+)和** 删除** (-)按钮交互,Count值应该分别递增和递减。

结论

在本文中,您学习了如何使用VoidCallbackFunction(X)来使用回调风格的事件来实现Ffltter控件之间的通信。

如果您想了解更多有关Ffltter的知识,请查看我们的Ffltter主题页面以获取练习和编程项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus