如何使用 VoidCallback 和 Function(x) 在带有 Flutter 的小部件之间进行通信

介绍

Flutter 项目的一个很好的范例是将你的小部件分成小的、可测试的单元,这些单元可以适应它们的上下文。

Flutter 为子和父小部件之间的回调样式事件提供VoidCallbackFunction(x)(其中x可以是不同的类型)。

在本文中,您将使用回调样式的事件在 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");
  }
}

编译你的代码并让它在模拟器中运行:

Flutter 应用程序的屏幕截图,显示计数为零

这将在屏幕上显示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.");
          },
        )
      ),
    );
  }
}

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

Output
Count 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父小部件。然后,之间加入valcount执行,并count进行更新。

编译你的代码并让它在模拟器中运行:

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

添加( +) 和删除( -) 按钮交互count值应分别增加和减少。

结论

在本文中,您学习了如何使用VoidCallbackFunction(x)使用回调样式的事件在 Flutter 的小部件之间进行通信。

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

觉得文章有用?

点个广告表达一下你的爱意吧 !😁