首页 > 解决方案 > 将 Widget Builders 之类的类成员提取到不同的文件中?

问题描述

在为我的 Flutter 应用程序开发一些屏幕时,我经常需要根据屏幕的状态动态渲染小部件。对于创建一个单独的小部件并包含它是有意义的情况,我会这样做。

但是,在许多用例中,我需要渲染的内容不适合小部件,并且会利用页面中的现有状态。因此,我使用构建器方法将适当的小部件呈现到页面。任何使用 Flutter 的人都知道,这可能会导致冗长的代码,您需要向上/向下滚动很多次才能找到您需要处理的内容。

为了更好的可维护性,我希望将这些构建器方法移动到单独的文件中,然后只包含它们。这将使处理呈现的特定代码小部件变得更加容易,并使屏幕小部件更清洁。

但我还没有找到一种正确的方法来提取动态小部件代码,它利用状态、调用更新状态等。我正在寻找一种类型的“包含”文件,它将代码插入主屏幕和渲染为好像它是核心代码的一部分。

这可能吗?如何实现?

标签: flutterdartflutter-layout

解决方案


随着成员的介绍extension,我遇到了这种非常巧妙的方式来实现您所描述的!

假设您有一个State这样定义的类:

class MyWidgetState extends State<MyWidget> {
  int cakes;

  @override
  void initState() {
    super.initState();

    cakes = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: (context) => Text('$cakes'),
    );
  }
}

如您所见,有一个局部变量cakes和一个builder函数。现在提取此构建器的非常简洁的方法如下:

extension CakesBuilderExtension on MyWidgetState {
  Widget cakesBuilder(BuildContext context) {
    return Text('$cakes');
  }
}

现在,即使扩展名放在另一个文件中,cakes也可以从 访问该成员。extension

现在,您将State像这样更新您的课程(已builder更改):

class MyWidgetState extends State<MyWidget> {
  int cakes;

  @override
  void initState() {
    super.initState();

    cakes = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: cakesBuilder,
    );
  }
}

cakesBuilder可以从 中引用,MyWidgetState即使它只在CakesBuilderExtension!

笔记

extension功能需要Dart 2.6。这在稳定频道中尚不可用,但我猜应该在 2019 年底左右。因此,您需要使用devor masterchannels: flutter channel devorflutter channel master并更新文件environment中的约束pubspec.yaml

environment:
  sdk: '>=2.6.0-dev.8.2 <3.0.0'

推荐阅读