背景
我们知道flutter是一种声明式的开发模式。编写代码时,widget一层嵌套一层,最后在Render层进行整理汇总后,完成绘制。这种嵌套的设计模式,在视觉上,往往会让我们产生疲惫感。
嵌套现象
如下,我们声明三个Widget,并把它们三个进行嵌套排列:
class AWidget extends StatefulWidget { final Widget child; const AWidget({Key key, @required this.child}) : super(key: key); @override _AWidgetState createState() => _AWidgetState(); } class _AWidgetState extends State
简单来说,Nested在build方法中,倒序遍历children,将每个item转换成_NestedHook对象。
并在遍历的过程中,将倒序排序中的前节点(我们后面所说的子节点)注入到每个item里面。第一个item注入的是Nested的child对象,其他item注入的是children队列中的前一个节点元素。
最终,注入的child,会响应在各自 buildWithChild方法中,作为入参存在。
Widget body() { return AWidget( child: BWidget( child: CWidget(), ), ); }
我们发现,在嵌套层数不多时,代码阅读性并没有受到太大的影响。但当嵌套关系变得复杂时,会严重影响编码体验。
处理 flutter 嵌套过深的利器 Nested
-
使用方式
我们使用Nested对上面的Demo进行优化修改:
AWidget 和 BWidget 需要分别继承 SingleChildStatefulWidget,SingleChildState 和 SingleChildStatelessWidget
///第一层父节点 class AWidget extends SingleChildStatefulWidget { const AWidget({Key key}) : super(key: key); @override _AWidgetState createState() => _AWidgetState(); } class _AWidgetState extends SingleChildState
继承后,需要实现 buildWithChild 方法,方法内 child 入参是 Nested 框架层处理注入的子节点[ 分别是 demo 中的 CWidget 和 BWidget ]。(实现原理我们在文末来聊)
- 子节点关系是如何表述的呢?
Widget body() { return Nested( children: [ AWidget(), BWidget(), ], child: CWidget(), ); }
代码说明:
按照倒序关系:
CWidget 作为 child 响应在 BWidget 的 buildWithChild 方法中;
BWidget 作为 child 响应在 AWidget 的 buildWithChild 方法中。
注意点: Nested 的 children 数组要求元素必须是 SingleChildWidget的子类
开发便利贴:
Nested 为我们提供如下工具类,已实现继承SingleChildWidget。前两种方式需要基础并重写buildWithChild方法。
- 对应StatelessWidget: SingleChildStatelessWidget
- 对应StatefulWidget: SingleChildStatefulWidget + SingleChildState
- 便捷方式,无需继承:SingleChildBuilder
Nested 实现原理分析
我们用 Demo 中的样例画了一张简图,整个过程更加清晰:
我们常用的 providerbloc 这两个库也是使用的 Nested 来处理代码的嵌套深渊
作者:李小轰
链接:https://www.jianshu.com/p/0687b41dc80c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。