[Flutter翻译]创建可重复使用的小工具的函数和类之间的区别是什么?

186 阅读4分钟

原文地址:flutteragency.com/what-is-the…

原文作者:flutteragency.com/author/john…

发布时间:2021年8月18日 - 6分钟阅读

image.png

Flutter提供了一组内置的小部件,以将不同的效果应用于移动应用程序。因此,在这篇文章中,我们将看到函数和类之间的区别是什么,以创建可重用的小部件。

让我们开始吧。

创建可重复使用的小部件的函数和类之间的区别是什么?

重要的区别。

它主要用于公共小部件,可以被重复使用。只使用一次的私有函数并不重要。尽管了解这种行为是很好的。

使用函数而不是类,有一个重要的区别。那就是,框架不知道函数,但可以看到类。

考虑一下下面的 "widget "函数。

Widget functionWidget({ Widget child}) {
  return Container(child: child);
}

你也可以用下面的方式建立它。

functionWidget(
  child: functionWidget(),
)

和它的类等价。

class ClassWidget extends StatelessWidget {
  final Widget child;

  const ClassWidget({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: child,
    );
  }
}

像这样使用。

ClassWidget(
  child: new ClassWidget(),
);

在函数的情况下,生成的widget树看起来像这样。

Container
  Container

而对于类,widget树是这样的。

ClassWidget
  Container
    ClassWidget
      Container

这很重要,因为它改变了框架在更新widget时的行为方式。

为什么这很重要?

通过使用函数将你的widget树分割成多个widget,你会将自己暴露在bug中,并错过一些性能优化的机会。

不能保证你通过使用函数会有bug。但是通过使用类,你可以确保你不会遇到这些问题。

这里有一些Dartpad上的交互式例子,你可以自己运行,以更好地理解这些问题。

下面是一个关于使用函数和类的区别的精选列表。

  1. 类。
  • 允许性能优化 constructor,更细化的重建
  • 确保在两个不同的布局之间切换时能正确地处理资源(函数可能会重复使用一些以前的状态)。
  • 确保热重载工作正常,使用函数可以破坏showDialogs和类似的热重载。
  • 被整合到小部件检查器中
  • 我们在devtool显示的widget树中看到ClassWidget,这有助于理解屏幕上的内容。
  • 我们可以覆盖debugFillProperties来打印传递给widget的参数是什么。

更好的错误信息。

  • 如果发生像ProviderNotFound这样的异常,框架会给你当前构建的widget的名字。
  • 如果你只在函数+生成器中分割了你的widget树,你的错误就不会有一个有用的名字。
  • 可以定义键
  • 可以使用上下文API
  • 函数。
  • 有较少的代码,可以使用代码生成的functional_widget来解决

对于Flutter框架

Dart同时支持程序化和OOP。但是,flutter框架完全是通过使用类(op)来构建的。因为一个大型的可管理的框架不能使用过程式创建。

  • 这里创建一个列表,说明他们使用类而不是函数来制作小部件的原因。
  • 大多数时候,build方法(子部件)会调用大量的同步和异步函数。
  • 所以build()方法需要保留在单独的类widget中。因为所有被build()方法调用的其他方法都可以保留在一个类中。
  • 使用widget类,你可以创建许多其他的类,而不需要重复写同样的代码。
  • 同时,使用继承(extend)和多态(override),你可以创建你自己的自定义类。

在下面的例子中,让我们通过扩展MaterialPageRoute来定制(Override)动画(因为它是我们要定制的默认过渡)。

class MyCustomRoute<T> extends MaterialPageRoute<T> {
  MyCustomRoute({ WidgetBuilder builder, RouteSettings settings })
      : super(builder: builder, settings: settings);

  @override                                      //Customize transition
  Widget buildTransitions(BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget child) {
    if (settings.isInitialRoute)
      return child;
    // Fades between routes. (If you don't want any animation, 
    // just return child.)
    return new FadeTransition(opacity: animation, child: child);
  }
}

函数不能为其参数添加条件。但是使用类部件的构造函数,你可以像下面这样做。

const Scaffold({
    Key key,
    this.bottomNavigationBar,
    this.bottomSheet,
    this.backgroundColor,
    this.resizeToAvoidBottomPadding,
    this.resizeToAvoidBottomInset,
    this.primary = true,
    this.drawerDragStartBehavior = DragStartBehavior.start,
    this.extendBody = false,
    this.extendBodyBehindAppBar = false,
    this.drawerScrimColor,
    this.drawerEdgeDragWidth,
  }) : assert(primary != null),
       assert(extendBody != null),
       assert(extendBodyBehindAppBar != null),
       assert(drawerDragStartBehavior != null),
       super(key: key);

函数不能使用const。类Widget可以在它们的构造函数中使用const(会影响主线程的性能)。

你可以使用同一个类/对象的实例创建任意数量的独立widget。但函数不能创建独立的widget实例,但重复使用可以。

结语。

感谢你和我们一起走过Flutter之旅!!!继续学习

继续学习 !!! 继续Fluttering !!!!

Flutter Agency 是我们专门为 Flutter 技术和 Flutter 开发人员提供的门户平台。该门户网站充满了来自Flutter的酷炫资源,如Flutter Widget指南、Flutter项目、代码库等。

Flutter Agency 是致力于 Flutter 技术的最受欢迎的在线门户之一。每天有数以千计的独特访问者来到这个门户网站,以提高他们对Flutter的认识。


www.deepl.com 翻译