在 Flutter 中自定义 View 有两种方式:

  1. 组合已有控件
  2. 自定义绘制

如何自定义绘制

有两个类做这件事情:

  • CustomPaint :会在绘制阶段提供一个 Canvas 画布
  • CustomPainter : 具体的画笔, 可配置画笔的颜色,路径等
CustomPaint(
painter: Sky(),
child: Center(
child: Text(
'Once upon a time...',
style: const TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w900,
color: Color(0xFFFFFFFF),
),
),
),
)
复制代码

当在绘制阶段时, CustomPaint 首先会调用 painter 在画布上进行绘制, 然后再绘制它的 child 控件, child 绘制完成之后会调用 foregroundPainter 进行绘制. 画布的坐标系和 CustomPaint 的坐标系匹配. CustomPaint 有个 Size 属性标识将绘制多大的区域, 绘制时这个 Size 属性将会传递到 CustomPainterpaint 方法中, 具体的绘制就在paint 方法中进行, void paint(Canvas canvas, Size size); 的方法签名中的两个参数:

  • canvas: 用于绘制的画布, 注意: 该画布是应用所有控件都在使用的, 所以通过这个画布其实是可以绘制充满屏幕的内容的
  • size: 表示应该绘制的区域大小, 每次绘制都应该限制在这个区域内, 否则可能会覆盖了其他控件的绘制结果

实例一

绘制一个矩形和圆角:

Widget build(BuildContext context) {
return CustomPaint(
painter: ColorPainter(),
size: Size(300, 200),
);
}
复制代码
class ColorPainter extends CustomPainter {

  final red = Color.fromRGBO(255, 0, 0, 1);
final blue = Color.fromRGBO(0, 0, 255, 1); @override
void paint(Canvas canvas, Size size) {
final paint = Paint();
final rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
// 注意这一句
canvas.clipRect(rect);
paint.color = blue;
canvas.drawRect(rect, paint);
paint.color = red;
canvas.drawCircle(Offset.zero, size.height, paint);
} @override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
复制代码
  • 定义了绘制区域大小, 为 CustomPaint 中的 size 属性
    final rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
复制代码
  • 绘制矩形区域
    canvas.drawRect(rect, paint);
复制代码
  • 绘制圆形

    • 圆心偏移量为: 0, 也就是 CustomPaint 的原点
    • 半径为区域的高度
    canvas.drawCircle(Offset.zero, size.height, paint);
复制代码

最需要注意的地方我觉得是 canvas.clipRect(rect); 这句. 这句表示只绘制给定的区域中的内容. 如果不写这句, 效果就是这样:

为什么会这样呢 ?

其实这就是 Size 这个参数的重要性, 因为 Canvas 是被所有控件公有的, 如果我们绘制时不指定区域大小, 那在进行一些形状的绘制时就会出现超出区域的问题.

实例二: 绘制一个带波纹的 CardView

最新文章

  1. SQL TO LINQ(Linqer神器)
  2. pietty and putty safe password
  3. 腾讯微博OAuthV2认证实现第三方登录
  4. hexo搭建博客上传至github
  5. 通过读取配置文件,启动mongodb
  6. Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)
  7. 浅谈Python装饰器
  8. VUE 绑定背景图片的写法
  9. 解决archlinux下QT程序,以及wineQQ无法输入中文(.xinitrc)
  10. pycaffe训练的完整组件示例
  11. luanet更名为distri.lua
  12. python中的str和repr函数的区别
  13. vasa构架
  14. 2012版辅助开发工具包(ADT)新功能特性介绍及安装使用
  15. linux下安装java jdk
  16. 《编写高质量代码:改善JavaScript程序的188个建议》学习小记(二)
  17. 2016.07.15——istringstream测试
  18. iuap
  19. 没有启动 ASP.NET State service错误的解决方法
  20. Rsyslog远程传输的几种方式

热门文章

  1. osg ifc数据渲染着色器
  2. Windows7 安装docker工具的方法
  3. Mysql常见索引介绍
  4. pytorch0.4.1安装
  5. (八)Centos之文件搜索命令locate
  6. jQuery学习二
  7. javascript DOM和DOM操作的四种基本方法
  8. MySQL 事务一览
  9. springboot集成webSocket能启动,但是打包不了war
  10. 龙芯PG10 安装uuid-ossp 的方法 复用瀚高数据库的 so文件