简介

flutter中有很多种Builder,尽管所有的builder都是结构器,然而不同的builder之间还是有很多差距的。明天咱们来具体介绍一下Builder,LayoutBuilder,StatefulBuilder这几个builder的应用。

Builder

Builder是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'));                  }),                );        },      ),    );  }

LayoutBuilder

Builder能够传递BuildContext, StatefulBuilder能够传递StateSetter,LayoutBuilder和下面提到的两个Builder很相似,不同的是LayoutBuilder能够提供父widget的大小。

咱们先来看下LayoutBuilder的定义:

class LayoutBuilder extends ConstrainedLayoutBuilder<BoxConstraints> 

能够看到LayoutBuilder继承的类是不同的。

LayoutBuilder须要传入一个builder属性,这个builder是一个LayoutWidgetBuilder对象:

typedef LayoutWidgetBuilder = Widget Function(BuildContext context, BoxConstraints constraints);

具体的应用办法和Builder很相似,不同的是咱们能够依据传入的BoxConstraints来进行对应的逻辑判断。

看一个具体的例子:

class LayoutBuilderApp extends StatelessWidget{  @override  Widget build(BuildContext context) {    return LayoutBuilder(      builder: (BuildContext context, BoxConstraints constraints) {        if (constraints.maxWidth > 500) {          return buildWidget1();        } else {          return buildWidget2();        }      },    );  }  Widget buildWidget1() {    return Center(      child: Container(        height: 700.0,        width: 700.0,        color: Colors.blue,      ),    );  }  Widget buildWidget2() {    return Center(      child: Container(        height: 200.0,        width: 200.0,        color: Colors.yellow,      ),    );  }

下面的例子中,咱们依据BoxConstraints的大小,来返回不同的Widget组件。

这在某些状况下是十分有用的。

总结

本文介绍了三个罕用的Builder,大家能够认真领会。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多内容请参考 www.flydean.com

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!