组装

组合的思想始终贯穿在框架设计之中
**
image.png

图 2 升级项 UI 整体结构示意图

image.png

图 3 上半部分 UI 结构示意图

image.png

图 4 下半部分 UI 结构示意图

使用的控件:

  • Row
  • Column

  • Padding

  • Expanded
  • ClipRRect

  • Image

  • FlatButton
  • Text

自绘

在原生 iOS 和 Android 开发中,我们可以继承 UIView/View,在 drawRect/onDraw 方法里进行绘制操作。其实,在 Flutter 中也有类似的方案,那就是 CustomPaint

CustomPaint 是用以承接自绘控件的容器,并不负责真正的绘制。既然是绘制,那就需要用到画布与画笔。

在 Flutter 中,画布是 Canvas画笔则是 Paint,而画成什么样子,则由定义了绘制逻辑的 CustomPainter 来控制。将 CustomPainter 设置给容器 CustomPaint 的 painter 属性,我们就完成了一个自绘控件的封装。

在下面的代码中,我们继承了 CustomPainter,在定义了绘制逻辑的 paint 方法中,通过 Canvas 的 drawArc 方法,用 6 种不同颜色的画笔依次画了 6 个 1/6 圆弧,拼成了一张饼图。最后,我们使用 CustomPaint 容器,将 painter 进行封装,就完成了饼图控件 Cake 的定义。

  1. class WheelPainter extends CustomPainter {
  2. // 设置画笔颜色
  3. Paint getColoredPaint(Color color) {//根据颜色返回不同的画笔
  4. Paint paint = Paint();//生成画笔
  5. paint.color = color;//设置画笔颜色
  6. return paint;
  7. }
  8. @override
  9. void paint(Canvas canvas, Size size) {//绘制逻辑
  10. double wheelSize = min(size.width,size.height)/2;//饼图的尺寸
  11. double nbElem = 6;//分成6份
  12. double radius = (2 * pi) / nbElem;//1/6圆
  13. //包裹饼图这个圆形的矩形框
  14. Rect boundingRect = Rect.fromCircle(center: Offset(wheelSize, wheelSize), radius: wheelSize);
  15. // 每次画1/6个圆弧
  16. canvas.drawArc(boundingRect, 0, radius, true, getColoredPaint(Colors.orange));
  17. canvas.drawArc(boundingRect, radius, radius, true, getColoredPaint(Colors.black38));
  18. canvas.drawArc(boundingRect, radius * 2, radius, true, getColoredPaint(Colors.green));
  19. canvas.drawArc(boundingRect, radius * 3, radius, true, getColoredPaint(Colors.red));
  20. canvas.drawArc(boundingRect, radius * 4, radius, true, getColoredPaint(Colors.blue));
  21. canvas.drawArc(boundingRect, radius * 5, radius, true, getColoredPaint(Colors.pink));
  22. }
  23. // 判断是否需要重绘,这里我们简单的做下比较即可
  24. @override
  25. bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this;
  26. }
  27. //将饼图包装成一个新的控件
  28. class Cake extends StatelessWidget {
  29. @override
  30. Widget build(BuildContext context) {
  31. return CustomPaint(
  32. size: Size(200, 200),
  33. painter: WheelPainter(),
  34. );
  35. }
  36. }