颤动:通过抽象森林🌲

您还记得` div.innerHTML =“ Hello World”`吗? 如果您确实愿意,也可以在“ Flutter”中执行此操作。

由于具有良好的层架构,“ Flutter”允许编写不同样式的代码。 但是在开始编码之前,我们应该先了解一下默认情况下现在如何工作,然后删除一些魔术抽象并进一步深入了一层。

Flutter具有三个主要层:

  • 🍏 “小部件”
  • 🍋 “渲染”
  • 🍆 “ dart.ui”

每个层都依赖于其先前的层,因此“小部件”层与“渲染”和“ dart.ui”层进行交互。 因此,“渲染”层与“ dart.ui”交互,对“小部件”一无​​所知。 是的,这就是正确实现的层体系结构的样子。

现在让我们为每个图层添加简短描述:

  • d “ dart.ui” —与渲染引擎进行交互的低级API。 只是一个普通的画布和一组在其上绘制线条和点的函数。
  • 🍋 “ Render”渲染) —此层与网络中的“ DOM”(文档对象模型)非常相似。 您有一棵可变的渲染对象
  • 🍏 “小部件” —此层类似于虚拟“ DOM”。 不可变的小部件

默认情况下,“ Flutter”会创建一个带有“ Widgets”层的项目:

  void main()=> runApp(新的MyApp()); 

在大多数情况下,这是一个不错的选择,因为每一层都隐藏了一些实现细节,并提供了干净而强大的抽象,可以快速编写复杂的应用程序。 但是,它不是免费的-每层都增加了计算成本和一组抽象,这对于某些类型的应用程序不太适合。 其中一个很好的例子是游戏应用,其中速度至关重要,“小部件”模型笨拙。 但是,开放而不进行框架修改的扩展总比没有好。

现在是时候编写一个没有“小部件”的简单计数器应用程序了。

  1. 首先,在终端/控制台中运行“ flutter create counter”。
  2. 打开“ lib / main.dart”并删除所有代码。
  3. 导入“ flutter / rendering.dart”包,该包提供一组与“ Render”层有关的渲染对象和功能。
  导入'package:flutter / rendering.dart'; 

4.现在编写我们的入口点-函数“ main”。

 导入'package:flutter / rendering.dart'; 
  void main(){ 

}

5.现在,我们将使用“ RenderingFlutterBinding(root:rootNode)”代替“ runApp(MyApp())”。 此功能将“ rootNode”附加到渲染视图。 作为“ rootNode”,我们获取“ RenderParagraph”对象并在屏幕上打印“ Hello World”。

 导入'package:flutter / rendering.dart'; 
  void main(){ 
最后的rootNode = RenderParagraph(
TextSpan(文本:“ Hello World!”),
textDirection:TextDirection.ltr,
);
  RenderingFlutterBinding(root:rootNode); 
}

现在,我们可以启动/“热重启”我们的应用程序并查看结果。 “ Hello World!”文本应显示在左上角。

6.让我们通过“ RenderPositionedBox”在屏幕上居中显示文本。

 导入'package:flutter / rendering.dart'; 
  void main(){ 
最后的rootNode = RenderParagraph(
TextSpan(文本:“ Hello World!”),
textDirection:TextDirection.ltr,
);
  RenderingFlutterBinding( 
根: RenderPositionedBox(childrootNode),
);
}

重新启动后,文本应在屏幕上居中。

此时,所有步骤看起来都与我们使用“小部件”编写代码时相同。 为了理解“渲染”对象和“小部件”之间的区别,让我们在用户点击文本时对其进行更改。

7.要处理点击,我将使用“ RenderPointerListener”。

 导入'package:flutter / rendering.dart'; 
  void main(){ 
最后的rootNode = RenderParagraph(
TextSpan(文本:“ Hello World!”),
textDirection:TextDirection.ltr,
);
  RenderingFlutterBinding( 
根目录:RenderPositionedBox(
子级: RenderPointerListener(
onPointerDown:(_)=> rootNode.text = TextSpan(text:“ Hi”),
子节点:rootNode,
),
),
);
}

如您所见,将文本从“ Hello World”更改为“ Hi”,我们只需更新/更改“ rootNode”对象的“ text”属性。 在后台,“ RenderParagraph”将通知渲染引擎“ text”属性已更改,我们需要重新绘制屏幕。 反过来,渲染引擎将选择适当的时间进行重画。 因此,“ Render”对象和“ Widgets”之间的主要区别在于“ Render” 对象是可变的,而“ Widgets”则不是。

8.现在,不难想象如何编写一个简单的计数器应用程序。

 导入'package:flutter / rendering.dart'; 
  void main(){ 
int计数器= 0;
  counterText(counter){ 
return TextSpan(text:“您已多次推送文本:$ counter”);
}
 最后的rootNode = RenderParagraph( 
counterText(counter)
textDirection:TextDirection.ltr,
);
  RenderingFlutterBinding( 
根目录:RenderPositionedBox(
子级:RenderPointerListener(
onPointerDown:(_)=> rootNode.text = counterText(counter + = 1)
子节点:rootNode,
),
),
);
}

而已。 谢谢!