flutter系列之:builder为构造器而生

目录

  • 简介
  • Builder
  • StatefulBuilder
  • LayoutBuilder
  • 总结
简介flutter中有很多种Builder , 虽然所有的builder都是构造器 , 但是不同的builder之间还是有很多差距的 。今天我们来详细介绍一下Builder , LayoutBuilder , StatefulBuilder这几个builder的使用 。
BuilderBuilder是flutter中最常用的builder , 它是一个StatelessWidget,如下所示:
class Builder extends StatelessWidget我们看下它的构造函数:
const Builder({Key? key,required this.builder,}) : assert(builder != null),super(key: key);可以看到Builder和普通的StatelessWidget的最大的差别就是需要传入一个builder属性 , 这个builder是一个WidgetBuilder类型的属性 , 
WidgetBuilder是这样定义的:
typedef WidgetBuilder = Widget Function(BuildContext context);可以看到WidgetBuilder实际上是一个返回Widget的函数 , 这个函数在Builder被包含在parent's build方法中的时候 , 会被调用 。
那么使用Builder和普通的StatelessWidget有什么区别呢?
我们举个例子 , 首先是在Scaffold中直接包含一个包括TextButton的Center widget , 如下所示:
Widget build(BuildContext context) {return Scaffold(body: Center(child: TextButton(child: Text('TextButton'),)),);}上面的Center也可以使用Builder来封装:
Widget build(BuildContext context) {return Scaffold(body: Builder(builder: (BuildContext context) {return Center(child: TextButton(child: Text('TextButton'),),);},),);}初看起来两者没有太大的区别 , 但是不同的是在下面的例子中 , 我们使用了Builder来构建body 。
Builder的builder方法中我们传入了一个context , 这个context是当前builder的context , 我们可以通过这个context来获取到一些平时比较难获取到的对象 。
对于Scaffold来说 , 它提供了一个of方法 , 可以根据传入的context来找到离context最近的Scaffold 。这也是我们使用builder的目的:
Widget build(BuildContext context) {return Scaffold(body: Builder(builder: (BuildContext context) {return Center(child: TextButton(onPressed: () {print(Scaffold.of(context).hasAppBar);},child: Text('TextButton'),),);},),);}如上 , 我们可以在builder中 , 调用Scaffold.of(context)方法来获取对应的Scaffold对象 。
如果只是使用普通的StatelessWidget的话 , 是没法拿到Scaffold对象的 。
StatefulBuilder上一节我们提到的Buidler实际上是一个StatelessWidget , 表明builder是无状态的 。
而StatefulBuilder则和Builder不同 , 它是有状态的:
class StatefulBuilder extends StatefulWidget可以看到StatefulBuilder继承自StatefulWidget 。
和Builder很类似 , StatefulBuilder也有一个builder属性 , 不过这个builder属性的类型是StatefulWidgetBuilder:
typedef StatefulWidgetBuilder = Widget Function(BuildContext context, StateSetter setState);可以看到StatefulWidgetBuilder被调用的时候 , 不仅传入了BuildContext , 还同时调用了setState方法 。
StateSetter方法会导致Widget重构 。
如果我们创建的widget是一个StatefulWidget的话 , 那么就可以尝试使用StatefulBuilder来代替:
Widget build(BuildContext context) {return Center(child: Builder(builder: (BuildContext context) {int clicked = 0;return Center(child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {return TextButton(onPressed: (){setState(() => {clicked = 1 });},child: Text('TextButton'));}),);},),);}

经验总结扩展阅读