flutter开发的官方推荐是响应式编程,响应式编程简单理解是数据流变化自动驱动view层刷新的一种开发方式;这样的开发让业务和view层彻底解耦,是很棒的一种开发思想,所以flutter的开发就成了widget的组装及其属性的数据绑定。但是我们很多时候不仅仅是进行数据绑定,view层也不能狭隘的理解为widget的组装与属性赋值,view层结合view相关的一些业务逻辑的处理才能让架构更为合理,比如view点击事件的设定、新的路由的打开、新的对话框的打开、动画相关的操作等,此时我们不仅需要在widget中进行一些业务逻辑的处理,我们还需要得到这个widget对于的BuildContext。下面的代码应该非常常见了吧:
body: Center(
child: Builder(
builder: (context) {
return Text("Builder").gesture(onTap: () {
showDialog(context: context, child: Text("dialog"));
});
},
),
),
如果你想在点击了某个组件之后对界面进行刷新,那么通常你需要定义一个StatefulWidget在需要刷新的地方调用setState,但是StatefulBuilder看起来也是一个不错的选择:
这里没有使用定义StatefulWidget的方式,因为这个逻辑很简单,定义StatefulWidget是麻烦而且没有必要的
body: Center(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Text("clickTimes$clickTimes").gesture(onTap: () {
setState(() {
clickTimes++;
});
});
},
),
),
以上Builder类和StatefulBuilder都是官方提供的类,以便开发者使用,但我们不能满足于简简单单的使用,我们还要知道他的本质。
那先来看看Builder吧:
class Builder extends StatelessWidget {
const Builder({
Key key,
@required this.builder,
}) : assert(builder != null),
super(key: key);
final WidgetBuilder builder;
@override
Widget build(BuildContext context) => builder(context);
}
Builder 的源码非常简单,其实就是一个StatelessWidget ,只不过是其build方法,通过传入的builder方法由使用者实现。再看看传入的builder的签名:
/// * [IndexedWidgetBuilder], which is similar but also takes an index.
/// * [TransitionBuilder], which is similar but also takes a child.
/// * [ValueWidgetBuilder], which is similar but takes a value and a child.
typedef WidgetBuilder = Widget Function(BuildContext context);
也很简单,就是一个参数为BuilderContext返回值为Widget的Fuction而已。
下面看看StatefulBuilder
class StatefulBuilder extends StatefulWidget {
const StatefulBuilder({
Key key,
@required this.builder,
}) : assert(builder != null),
super(key: key);
final StatefulWidgetBuilder builder;
@override
_StatefulBuilderState createState() => _StatefulBuilderState();
}
class _StatefulBuilderState extends State {
@override
Widget build(BuildContext context) => widget.builder(context, setState);
}
StatefulBuilder 的源码也非常简单,其实就是一个StatefulWidget ,与Builder的不同之处在于其传入的builder的函数签名包含两个参数,多了一个setState,setState是一个函数引用,调用这个函数可以导致这个StatefulWidget 的bulide方法被调用,StatefulBuilder 就是通过传入的builder方法将setState传递给使用者,在外部刷新这个widget。再看看StatefulBuilder 的builder的签名:
/// Signature for the builder callback used by [StatefulBuilder].
///
/// Call [setState] to schedule the [StatefulBuilder] to rebuild.
typedef StatefulWidgetBuilder = Widget Function(BuildContext context, StateSetter setState);
非常简单,就是参数为BuilderContext和StateSetter 返回值为Widget的Fuction而已。
以上就是关于Builder和StatefulBuilder的探究过程。